マージ間隔
バックルの公式ソリューションが 2日前に投稿されました。
方法1:並べ替え
アイデア
間隔の左端でソートする場合、ソートされたリストでは、マージできる間隔は連続している必要があります。次の図に示すように、青、黄、緑でマークされた間隔は、並べ替えられたリストで連続する大きな間隔に結合できます。
アルゴリズム
配列を使用しmerged
て最終的な回答を 保存します。
最初に、リストの間隔を左端点の昇順で並べ替えます。次に、最初の間隔をmerged
配列に追加し、 後続の各間隔を順に検討します。
-
現在の間隔の左端が配列の
merged
最後の間隔の右端の後ろにある 場合、それらは一致しません。この間隔を配列のmerged
最後に直接追加できます -
そうでない場合、それらは一致
merged
し、配列内の最後の間隔の右端を現在の間隔の右端で更新し 、2つのうち大きい方に設定する必要があります。
正当性の証明
上記のアルゴリズムの正しさは、カウンタープルーフの方法で証明できます。ソートされた配列では、マージする必要のある2つの区間をマージできません。つまり、そのようなトリプル(i、j、k)(i、 j、k)と配列内の3つの間隔a [i]、a [j]、a [k] a [i]、a [j]、a [k]は、i <j <ki <j <kおよび(a [i]、a [k])(a [i]、a [k])は組み合わせることができますが、(a [i]、a [j])(a [i]、a [j])および( a [j]、a [k])(a [j]、[k])はマージできません。これは、次の不等式を満たしていることを示しています。
a [i] .end <a [j] .start \ quad(a [i] \ text {and} a [j] \ text {cannot canbined})\\ a [j] .end <a [k]。 start \ quad(a [j] \ text {and} a [k] \ text {cannot bebind})\\ a [i] .end \ geq a [k] .start \ quad(a [i] \ text {そして} a [k] \ text {マージ可能})\\ a [i] .end <a [j] .start(a [i]と[j]はマージできません)a [j] .end <a [ k] .start(a [j]とa [k]はマージできません)a [i].end≥a[k] .start(a [i]とa [k]はマージできます)
これらの不等式を組み合わせます(明らかな不等式a [j] .start \ leq a [j] .enda [j].start≤a[j] .endがあることに注意してください)。
a [i] .end <a [j] .start \ leq a [j] .end <a [k] .starta [i] .end <a [j].start≤a[j] .end <a [ k] .start
矛盾があります!これは、仮定が正しくないことを示しています。したがって、マージできるすべての間隔は必然的に連続しています。
- Python3
- C ++
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
intervals.sort(key=lambda x: x[0])
merged = []
for interval in intervals:
# 如果列表为空,或者当前区间与上一区间不重合,直接添加
if not merged or merged[-1][1] < interval[0]:
merged.append(interval)
else:
# 否则的话,我们就可以与上一区间进行合并
merged[-1][1] = max(merged[-1][1], interval[1])
return merged
複雑さの分析
-
時間の複雑さ:O(n \ log n)O(nlogn)、ここでnnは間隔の数です。並べ替えのオーバーヘッドを除いて、必要な線形スキャンは1つだけなので、主な時間のオーバーヘッドは並べ替えO(n \ log n)O(nlogn)です。
-
スペースの複雑さ:O(\ log n)O(logn)。ここで、nnは間隔の数です。ここで計算されるのは、回答の保存に加えて使用される追加のスペースです。O(\ log n)O(logn)は、ソートに必要なスペースの複雑さです。