題目描述
題解和思路
**優質**
閒話
給你乙個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?請你找出所有滿足條件且不重複的三元組。注意:答案中不可以包含重複的三元組。
給定陣列 nums = [-1, 0, 1, 2, -1, -4],滿足要求的三元組集合為:
[[-1, 0, 1],
[-1, -1, 2]
]
聰明的小夥伴是不是一看題目之後,仔細的想了想第一思路就是三重迴圈,直接出來答案!其實是對的,但是轉念一想時間複雜度o(n^3),這是乙個很長的時間,而且你有麼有想過,如果你直接三重迴圈,可能會輸出重複的三元陣列.所以簡單直接的三重迴圈是不可取得,需要進行優化.
第一步優化,我們先讓輸出不會輸出重複的三元陣列,這個陣列是無序,我們可以先進行排序,排序之後是有序的,然後輸出的三元陣列(a,b,c)保證a
第二步優化,我們就要減小時間複雜度,讓時間複雜度從三次降到二次,那麼你想想是不是要少一重迴圈,至於少哪一重,你可以先這樣考慮,在a不變的情況下,b必須小於c,如果b變大了,那麼c就要減小,既然要這樣,讓b從頭開始遍歷,而c則從尾部開始遍歷.而且我們要少一重迴圈,那麼可以用雙指標的方法去完成我們的要求.
已經減了枝,也滿足了要求,第三步就不是優化了,你得寫**了!
其實寫題目我們一般腦袋第一思考都是暴力去解決的,(天才就不考慮了),很多時候你可以用很多方法去給你的暴力方法去優化,用二分方法,排序等等很多方法優化的,一直優化,知道時間複雜度滿足要求的.
class
solution
// c 對應的指標初始指向陣列的最右端
int third = n -1;
int target =
-nums[first]
;// 列舉 b
for(
int second = first +
1; second < n;
++second)
// 需要保證 b 的指標在 c 的指標的左側
while
(second < third && nums[second]
+ nums[third]
> target)
// 如果指標重合,隨著 b 後續的增加
// 就不會有滿足 a+b+c=0 並且 bif
3sum/solution/san-shu-zhi-he-by-leetcode-solution/
我的**和官方其實差不多的,我沒有寫注釋,所以你們看看這個官方的吧!
寫完了leetcode題目我們也去看看別人的優質**,提高自己,所以看看時間複雜度更低的**吧!!
class
solution
for(
int idx =
0; idx < len -2;
++idx)
if(idx >
0&& fix == nums[idx -1]
)int left = idx +1;
int right = len -1;
while
(left < right));
++left;
--right;
}else
if(nums[left]
== nums[left -1]
)else
if(nums[right]
== nums[right +1]
)else);
++left;
--right;}}
else
if(total >
-fix)
else}}
return res;}}
;
這個**很強,時間只需要40ms我們得多學習學習,沒有注釋,所以你們好好思考一下!!!
最近考試挺多的,慢慢的也接近了尾聲了.這幾天我得好好複習高數,這是乙個難題!!!
加油吧各位!!
每日一題 LeetCode 15 三數之和
每日一題,防止痴呆 給你乙個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c 使得 a b c 0 請你找出所有滿足條件且不重複的三元組。先分享乙個自己的最後沒得出結果的思路吧 可能這段時間一會做題一會不做題,腦子有點慢 我一開始的想法是因為是三個數相加得0,那麼其實...
每日一題 LeetCode
在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。示例 1 輸入 7,5,6,4 輸出 5 限制 0 陣列長度 50000 思想是 分治演算法 所有的 逆序對 於 3 個部分 左邊區間的逆序對 右邊區間的逆序對 橫跨兩個區間的...
LeetCode每日一題(三) 移除元素
題目描述 給定乙個陣列 nums 和乙個值 val,你需要原地移除所有數值等於 val 的元素,返回移除後陣列的新長度。不要使用額外的陣列空間,你必須在原地修改輸入陣列並在使用 o 1 額外空間的條件下完成。元素的順序可以改變。你不需要考慮陣列中超出新長度後面的元素。示例 1 給定 nums 3,2...