題目
插入區間
給出乙個無重疊的 ,按照區間起始端點排序的區間列表。
在列表中插入乙個新的區間,你需要確保列表中的區間仍然有序且不重疊(如果有必要的話,可以合併區間)。
示例 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匹馬至少都跑了一次,最少五輪,且每輪能排出名次 由於最終只要最快的三...