專欄:50多種數據結構徹底征服
專欄:50多種經典圖論算法全部掌握
2025年 1 月 15 日馬斯克在X(以前的推特)上發文稱:他們招聘軟件工程師不關心你的學歷,或者你是否上過大學以及是否在哪個大廠工作過,只需要展示你的代碼即可。不過我感覺這不是很靠譜,因為讀代碼要比看簡歷難多了,發給你一份代碼要看到啥時候,并且看代碼還需要專業的人才能看,hr不一定看的懂,現在很多hr連簡歷都看不過來,直接使用篩選功能。不過這也給那些學歷不高但能力很強的人更多的機會。
--------------下面是今天的算法題--------------
來看下今天的算法題,這題是LeetCode的第57題:插入區間。
問題描述
來源:LeetCode第57題
難度:中等
給你一個無重疊的,按照區間起始端點排序的區間列表 intervals,其中 intervals[i] = [starti, endi] 表示第 i 個區間的開始和結束,并且 intervals 按照 starti 升序排列。同樣給定一個區間 newInterval = [start, end] 表示另一個區間的開始和結束。
在 intervals 中插入區間 newInterval,使得 intervals 依然按照 starti 升序排列,且區間之間不重疊(如果有必要的話,可以合并區間)。返回插入之后的 intervals。
示例1:
輸入:intervals = [[1,3],[6,9]], newInterval = [2,5] 輸出:[[1,5],[6,9]]
示例2:
輸入:intervals = [[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] 重疊。
0 <= intervals.length <= 10^4
intervals[i].length == 2
0 <= starti <= endi <= 10^5
intervals 根據 starti 按 升序 排列
newInterval.length == 2
0 <= start <= end <= 10^5
問題分析
這題說的是原來的區間是按照起始點排序的,且區間沒有重疊。讓我們在原來的區間插入一個新的區間,如果有重疊就把他們合并,如下圖所示,因為區間[1,3]和區間[2,5]有重疊,
這里要判斷要合并的區間和上面的哪些區間有重疊,因為上面的區間都已經按照起始點排序了,如果 當前區間的終點小于合并區間的起始點, 他們是沒有重疊的 ,或者 當前區間的起始點大于合并區間的終點 ,他們也是沒有重疊的。
沒有重疊的區間只需要單獨保存下來,有重疊的區間需要合并。
JAVA:
public int[][] insert(int[][] intervals, int[] newInterval) { List
ans = new ArrayList<>(); for (int[] interval : intervals) { if (newInterval == null || interval[1] < newInterval[0]) { // 前面單獨的添加進來,或者已經合并完了,把后面的添加進來 ans.add(interval); } else if (interval[0] > newInterval[1]) { ans.add(newInterval);// 后面單獨的區間。 ans.add(interval); newInterval = null; } else {// 合并區間 newInterval[0] = Math.min(newInterval[0], interval[0]); newInterval[1] = Math.max(newInterval[1], interval[1]); } } // 如果合并之后的區間沒有保存下來,要保存下來 if (newInterval != null) ans.add(newInterval); return ans.toArray(new int[ans.size()][]); }
C++:
public: vector
> insert(vector
> &intervals, vector
&newInterval) { vector
> res; bool finish = false;// 合并完了,后面的不需要再合并了,直接添加 for (auto const &interval: intervals) { if (finish || interval[1] < newInterval[0]) { res.emplace_back(interval);// 前面單獨 } else if (interval[0] > newInterval[1]) {// 后面單獨 res.emplace_back(newInterval); res.emplace_back(interval); finish = true; } else {// 有交叉,合并 newInterval[0] = min(newInterval[0], interval[0]);//get min newInterval[1] = max(newInterval[1], interval[1]);//get max } } if (!finish) res.emplace_back(newInterval); return res; }
Python:
def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]: ans = [] for interval in intervals: if not newInterval or interval[1] < newInterval[0]: # 前面單獨的添加進來,或者已經合并完了,把后面的添加進來 ans.append(interval) elif interval[0] > newInterval[1]: ans.append(newInterval[:]) # 后面單獨的區間。 ans.append(interval) newInterval.clear() else: # 合并區間 newInterval[0] = min(newInterval[0], interval[0]) newInterval[1] = max(newInterval[1], interval[1]) # 如果合并之后的區間沒有保存下來,要保存下來 if newInterval: ans.append(newInterval) return ans
筆者簡介
博哥,真名:王一博,畢業十多年, 作者,專注于 數據結構和算法 的講解,在全球30多個算法網站中累計做題2000多道,在公眾號中寫算法題解800多題,對算法題有自己獨特的解題思路和解題技巧,喜歡的可以給個關注,也可以 下載我整理的1000多頁的PDF算法文檔 。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.