亞馬遜筆試題LC57插入區間 合併區間思想

2021-10-10 06:12:06 字數 3736 閱讀 8245

題目

插入區間

給出乙個無重疊的 ,按照區間起始端點排序的區間列表。

在列表中插入乙個新的區間,你需要確保列表中的區間仍然有序且不重疊(如果有必要的話,可以合併區間)。

示例 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] 重疊。

思路題意很簡單,就是要把一段區間陣列與乙個區間進行合併,返回結果。 如圖:

這個題目是個hard難度,但是我認為並不算特別複雜,可能因為是力扣早期的題目,所以對於困難的定義不是特別的準確。

第一種思路就是類似於堆疊的思想,把開閉的所有值排列在乙個有序陣列上,開區間就放進去,閉區間就移除元素,每次棧的第乙個放入的元素就是開區間的值,每次棧為空的時候就是閉區間的值,這樣就能夠達到合併的效果。

為了更好的實現,首先把節點進行排序,並且進行標記是開還是關區間,用1表示開,-1表示關,只要在遍歷的時候進行累計,如果累計為0,說明是關區間。

**實現:

public

int[

]insert

(int

intervals,

int[

] newinterval);if

(newinterval == null || newinterval.length ==0)

return intervals;

// 1為開口,-1為關閉

list

positionlist =

newarraylist

<

>()

;for

(int i =

0;i < intervals.length;i ++

) positionlist.

add(

newposition

(newinterval[0]

,1))

; positionlist.

add(

newposition

(newinterval[1]

,-1)

);// 根據點的位置進行排序

collections.

sort

(positionlist,

(o1, o2)

-> o1.val - o2.val)

;// 累計開閉值

int count =0;

list

> retlist =

newarraylist

<

>()

;int start = integer.max_value, end = integer.max_value;

for(

int i =

0;i < positionlist.

size()

;i ++

)

count += p.status;

if(count ==

1&& start == integer.max_value)

else

if(count ==0)

if(start != integer.max_value && end != integer.max_value)

}int

ret =

newint

[retlist.

size()

][2]

;for

(int i =

0;i < retlist.

size()

;i ++

)return ret;

}class

position

}

複雜度分析:因為有排序邏輯,時間複雜度為nlogn,儲存了positionlist空間複雜度為n。

雖然解出來了,但是有優化空間,可以畫個圖,發現肉眼很容易識別這樣的合併區間結果,只要模擬好我們大腦合併的思路,其實很快能找到最優解。

我們遍歷intervals區間,intervals[i]為當前區間、標誌l為左邊界,r為右邊界。left為newintervals的左邊界,right為newintervals的右邊界。

如果r < left 或則l > right 說明沒有重疊,直接新增區間in在這裡插入**片tervals[i]。

如果r >= left && l <= right說明有重疊,那就合併left為min(left, l),right為max(right, r)。

什麼時候寫入合併區間呢,就是第乙個l > right的時候。

當然可能最後是乙個大區間,那就永遠沒有r > right,所以遍歷完了還要判斷一下是否是這種情況需要特殊處理一下。

**如下:

public

int[

]insert

(int

intervals,

int[

] newinterval);if

(newinterval == null || newinterval.length ==0)

return intervals;

list<

int[

]> list =

newarraylist

<

>()

;int left = newinterval[0]

, right = newinterval[1]

;// 標示是否新增了合併

boolean added =

false

;for

(int i =

0;i < intervals.length;))

; added =

true;}

list.

add(intervals[i]);

}else

if(l <= right && r >= left)

i ++;}

// 可能 intervals 最後都合併為乙個大的區間if(

! added) list.

add(

newint

);// 複製結果

int[

] ans =

newint

[list.

size()

][2]

;for

(int i =

0;i < list.

size()

;i ++

)return ans;

}

複雜度分析:遍歷一次,時間複雜度為n,空間複雜度不算結果就是1。

華為筆試題(5)

一 驗證尼科徹斯定理,即 任何乙個整數m的立方都可以寫成m個連續奇數之和。例如 1 3 1 2 3 3 5 3 3 7 9 11 4 3 13 15 17 19 輸入描述 輸入乙個int整數 輸出描述 輸出分解後的string 示例1 輸入 6 輸出 31 33 35 37 39 41 public...

蘑菇街筆試題5

題目描述 輸入描述 一行由小寫字母構成的字串,字串長度小於等於10 輸出描述 yes no 例子 coco 輸出 yes 如下 bool ispalindrome string s int main string input while cin input if input.size 0 input...

筆試題 5 賽馬排名問題

題 有25匹馬,每匹馬都以恆定的速度賽跑,當然馬與馬之間的速度是不相等的,總共有5個賽道,就是說每輪最多只能有5個馬同時賽跑。問題是 要確定出跑的最快的前三名馬,需要最少多少輪比賽?思路 毫無懸念,一匹馬只有跑了才能看出其速度,25匹馬至少都跑了一次,最少五輪,且每輪能排出名次 由於最終只要最快的三...