原題
間隔の開始点と終了点で並べ替えられた重複しない間隔のリストを提供します。
新しい範囲をリストに挿入するときは、リスト内の範囲がまだ順序付けられており、重複していないことを確認する必要があります (必要に応じて範囲を結合します)。
例 1:
入力:間隔 = [[1,3],[6,9]]、newInterval = [2,5] 出力: [[1,5],[6,9]]
例 2:
入力:間隔 = [[1,2],[3,5],[6,7],[8,10],[12,16]]、newInterval = [4,8] 出力: [[ 1,2 ] ],[3,10],[12,16]] 説明:これは、新しい間隔が[4,8]
と重なっているためです[3,5],[6,7],[8,10]
。
例 3:
入力:間隔 = []、newInterval = [5,7] 出力: [[5,7]]
例 4:
入力:間隔 = [[1,5]]、新しい間隔 = [2,3] 出力: [[1,5]]
例 5:
入力:間隔 = [[1,5]]、新しい間隔 = [2,7] 出力: [[1,7]]
ヒント:
0 <= intervals.length <= 104
intervals[i].length == 2
0 <= intervals[i][0] <= intervals[i][1] <= 105
intervals
intervals[i][0]
昇順で並べ替えますnewInterval.length == 2
0 <= newInterval[0] <= newInterval[1] <= 105
LeetCode 公式ウェブサイト - 世界中のオタクに愛されるテクノロジー成長プラットフォーム
問題解決のアイデア
間隔がすでに順序付けられており、重複がないことを考慮すると、間隔を 1 つずつ取り出して、挿入する間隔 newInterval と比較するだけで済みます。Interval と newInterval の相対的な位置、およびそれらが重複するかどうかに応じて、議論は次の状況に分類できます。
1. 間隔が newInterval の左側にあり、重複がない場合は、その間隔を挿入し、比較のために後続の間隔を取り出します。
2. 間隔が newInterval の右側にあり、重複がない場合は、最初に newInterval を挿入し、次に間隔を挿入し、次に残りの間隔を直接挿入します。
3. 間隔と newInterval が重複する場合は、間隔と newInterval を新しい newInterval としてマージし、後続の間隔を比較のために取り出します。
便宜上、newInterval が挿入されたかどうかを記録するためにフラグを使用する必要があります。間隔トラバースが終了し、newInterval が挿入されていない場合は、最後まで挿入されます。
完全な実装は次のとおりです。
class Solution {
public:
vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
int left = newInterval[0];
int right = newInterval[1];
bool placed = false;
vector<vector<int>> ans;
for (const auto& interval: intervals) {
if(interval[0] > right ){
if(!placed){
ans.push_back({left,right});
placed=true;
}
ans.push_back(interval);
}else if(interval[1] < left){
ans.push_back(interval);
}else{
left = min(left,interval[0]);
right = max(right,interval[1]);
}
}
if(!placed){
ans.push_back({left,right});
}
return ans;
}
};
ここで注意すべき点の 1 つは、挿入パフォーマンスを最適化するために C++ で emplace_back を使用することが多いということです。ただし、emplace_back(1,5) は実際には、vector<int>{1,5} ではなく、vector<int>(1,5) を挿入するため、ここでは emplace_back を使用できません。前者は要素 5 を 1 つだけ持つベクトルであり、後者は 2 つの要素 1 と 5 からなるベクトルです。