iT邦幫忙

2024 iThome 鐵人賽

DAY 20
0
佛心分享-刷題不只是刷題

刷題筆記系列 第 20

[Day20] Merge Intervals

  • 分享至 

  • xImage
  •  

Given an array of intervals where intervals[i] = [startᵢ, endᵢ], merge all overlapping intervals, and return an array of the non-overlapping intervals that cover all the intervals in the input.

給定一個區間陣列,其中 intervals[i] = [startᵢ, endᵢ],請合併所有重疊的區間,並回傳一個不重疊的區間陣列,且這些區間必須包含陣列intervals中所有的區間範圍。

https://ithelp.ithome.com.tw/upload/images/20240901/201686672mZHJSz6kw.png


我們先來回顧一下,根據昨天的Merge Intervals介紹,區間重疊的情境有以下六種組合,包含:

  1. a 和 b 不重疊,a 開始、b 結束
  2. a 和 b 重疊,a 開始、b 結束
  3. a 和 b 重疊,a 完全覆蓋 b
  4. a 和 b 重疊,b 開始、a 結束
  5. a 和 b 重疊,b 完全覆蓋 a
  6. a 和 b 不重疊,b 開始、a 結束

一開始我本來看完題目,就開始很認真地把要合併的情況,一一用if判斷寫出來,但寫到最後,開始測試卻發現完全行不通,寫了一堆的判斷去決定什麼時候要合併,反而沒有辦法有效地進行合併區間,因為就如上面詳列的六種情境,要一一列出反而很混亂。

後來改變策略,既然有a區間開始早於b區間開始的情況,也有b區間開始早於a區間開始的情況(哇!好饒舌啊!),想到這邊已經亂掉了。

先簡化問題吧!其實總結來說,如果先把所有區間的起始值,進行排序,由小至大排列,確保了合併的過程中,只需確認每個區間的結束點是否重疊就可以了!

步驟

  1. 按照所有區間的startᵢ進行排序
  2. 用一個空的陣列mergedArr存放合併結果,一開始就先把intervals的第一個區間放進去
  3. 使用for loop遍歷整個intervals
  4. 判斷只要startᵢ比陣列mergedArr中最後一個區間裡面的end還要大,表示有重疊的情況,那就進行合併,兩者取最大值,做為新的區間結束值

程式碼

var merge = function(intervals) {
    intervals = intervals.sort((a, b) => a[0] - b[0]);
    let mergedArr = [intervals[0]];
    for (let i = 1; i < intervals.length; i ++){
        if (mergedArr[mergedArr.length - 1][1] >= intervals[i][0]){
            mergedArr[mergedArr.length - 1][1] = Math.max(mergedArr[mergedArr.length - 1][1], intervals[i][1]); 
        } else {
            mergedArr.push(intervals[i]);
        }  
    }
    return intervals = mergedArr;
};

最後發現,這題的關鍵,怎麼好像是要先想到排序呀?哈哈哈~


上一篇
[Day19] Patterns: Merge Intervals
系列文
刷題筆記20
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言