Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonでカット区間と交差しない区間を求めるプログラムの実装方法

ソート済みで互いに重なり合わない区間(インターバル)のリストと、削除対象となる1つの区間「カット」が与えられたとします。この課題では、カット区間と交差している部分をすべて取り除き、残った区間を新しいリストとして返すプログラムを作成します。

例えば、入力が intervals = [[2, 11], [13, 31], [41, 61]]、cut = [8, 46] の場合、出力は [[2, 8], [46, 61]] になります。

解決のためのアルゴリズム

以下の手順で問題を解くことができます。

  1. カット区間の始点・終点をそれぞれ cut_start、cut_end に代入します。
  2. 結果を格納するための空リスト ans を用意します。
  3. intervals 内の各区間 (start, end) に対して次の処理を行います。
    max(cut_start, start) < min(end, cut_end) が成立するとき、その区間はカットと交差しています。この場合、
    ・start < cut_start ならば、区間 [start, cut_start] を ans に追加する
    ・end > cut_end ならば、区間 [cut_end, end] を ans に追加する
    一方、条件が成立しない(交差していない)場合は、元の区間 [start, end] をそのまま ans に追加します。
  4. すべての区間を処理し終えたら、ans を返します。

実装例(Pythonコード)

class Solution:
    def solve(self, intervals, cut):
        cut_start, cut_end = cut
        ans = []
        for start, end in intervals:
            if max(cut_start, start) < min(end, cut_end):
                # カットと交差している場合は、はみ出た部分だけを残す
                if start < cut_start:
                    ans.append([start, cut_start])
                if end > cut_end:
                    ans.append([cut_end, end])
            else:
                # 交差していない場合はそのまま追加
                ans.append([start, end])
        return ans

ob = Solution()
intervals = [[2, 11], [13, 31], [41, 61]]
cut = [8, 46]
print(ob.solve(intervals, cut))

入力

[[2, 11], [13, 31], [41, 61]], [8, 46]

出力

[[2, 8], [46, 61]]

処理の流れを詳しく解説

サンプル入力における各区間の処理は次のとおりです。

  • [2, 11]:max(8, 2) = 8 < min(11, 46) = 11 となり、カットと交差しています。start = 2 が cut_start = 8 より小さいため左側の [2, 8] が残ります。一方、end = 11 は cut_end = 46 より大きくないため、右側は残りません。
  • [13, 31]:max(8, 13) = 13 < min(31, 46) = 31 で交差していますが、区間全体がカット範囲に含まれているため、何も残りません。
  • [41, 61]:max(8, 41) = 41 < min(61, 46) = 46 で交差しています。end = 61 が cut_end = 46 より大きいため、右側の [46, 61] が残ります。

このように、交差判定には「2つの始点のうち大きい方」が「2つの終点のうち小さい方」より小さいかどうかという条件式を使うのがポイントです。これは2つの区間が重なっているかどうかを判定する際の定番手法なので、覚えておくとさまざまな場面で応用できます。

  1. Pythonで行列の転置を求めるプログラム

    この記事では、与えられた問題に対する解法とアプローチについて詳しく解説します。 問題文 ある行列が与えられたとき、その転置を同じ行列に格納し、結果を表示する必要があります。 行列の転置とは、行を列に、列を行に入れ替えたものです。言い換えれば、行列Aの転置は、要素A[i][j]をA[j][i]と入れ替えることで得られます。 実装例 N = 4 def transpose(A): for i in range(N): for j in range(i+1, N): A[i][j], A[j][i] = A[j][i], A[i][j] # ドライ

  2. Pythonで配列(リスト)の合計を求める方法をわかりやすく解説

    この記事では、配列(リスト)の合計値を求めるという問題に対して、Pythonでの解決策とアプローチをわかりやすく解説します。 問題の定義 配列が入力として与えられたとき、その配列に含まれるすべての要素の合計を計算することを目標とします。 例えば、[1, 2, 3, 4, 5] という配列が与えられた場合、出力は 15 になります。 アプローチ1:ループを使った素朴な方法(総当たり法) 最も基本的な方法は、リストを先頭から順に走査し、各要素を合計用の変数に加算していくやり方です。手順は以下の通りです。 合計を格納する変数を 0 で初期化します。 for ループでリストの各要素を取り出し、順番に