タイトル
https://leetcode-cn.com/problems/merge-intervals/
一連の間隔を指定して、重複するすべての間隔をマージしてください。
例1:
入力:[[1,3]、[2,6]、[8,10]、[15,18]]
出力:[[1,6]、[8,10]、[15,18]]
説明:間隔[1,3]と[2,6]はオーバーラップし、それらを[1,6]にマージします。
例2:
入力:[[1,4]、[4,5]]
出力:[[1,5]]
説明:間隔[1,4]と[4,5]は重複する間隔と見なすことができます。
問題解決のアイデア(エレガントでないバージョン)
- 最初にリストを左でソートします
- 2つの範囲[0]と[1]を比較します
- 交差する場合、マージ、更新[0]、破棄[1]
- 交差なしの[0]を結果リストに追加
- リストの長さが2未満になるまで、[0]と[1]についてこのプロセスを繰り返します。
- リストにまだコンテンツがある場合は、結果リストに追加します
コード(エレガントバージョンの下)
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
# - sort intervals by left
intervals = sorted(intervals, key=lambda x:x[0])
res = []
while len(intervals)>=2:
# - if overlap, update [0] and drop [1]
if intervals[1][0] <= intervals[0][1]:
intervals[0][1] = max(intervals[0][1], intervals[1][1])
intervals.pop(1)
else:
# - put [0] into res and pop [0]
res.append(intervals[0])
intervals.pop(0)
# - add last one to res if has one
if intervals:
res.append(intervals[0])
return res
問題解決のアイデア(エレガントなバージョン)
既存のリストに対する削除操作が多すぎるという以前の考えは、実際には不要です。
結果リストのみを処理する必要があります。
- 左から最初に並べ替え
- 結果リストの範囲と最後の範囲を順番に確認する
- マージできる場合は、結果リストの最後の範囲を更新します
- それ以外の場合は、結果リストの最後に追加します
コード(Elegant Edition)
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
# - sort intervals by left
intervals = sorted(intervals, key=lambda x:x[0])
res = []
for x in intervals:
if not res:
res.append(x)
elif x[0] <= res[-1][1]:
res[-1][1] = max(res[-1][1], x[1])
else:
res.append(x)
return res