LeetCode 15 三數之和

2021-08-24 20:41:45 字數 2124 閱讀 5870

15. 三數之和

比較容易想到的就是,求三數之和等於0,可以等價於求兩個數的和,然後看這個和的相反數是否在nums裡面。

但是 t_t這樣的話複雜度太高了,會超時,捂臉,最後三個case,怎麼改都超時……

bool find(vector

nums, int nums_sz, int target, int m, int n)

return

false;

}vector

> threesum(vector

& nums) }}

int s_sz = s.size();

for (set

>::iterator it = s.begin(); it != s.end(); it++)

return res;

}

最後沒辦法去網上找了下人家的sol,還有這篇(沒有優化),發現是我之前的思路不夠好,而且沒有優化到很好的地步。

總體思路是先排序(從小到大),然後以每乙個數為起始,在它的右邊不斷縮小範圍看是否有符合條件的數。

首先需要將原陣列排序,這裡可以用c++的sort介面就行:sort(nums.begin(), nums.end());

這麼排序我覺得個好處是當找到滿足條件的三元組時,不需要判斷結果的二維vector中是否已經包含了當前要放進去的子陣列;

然後對於當前的數nums[i],在他的右邊用下標leftright進行縮小範圍的遍歷;

如果sum = nums[i] + nums[left] + nums[right]; > 0,那麼說明nums[right]大了,因此right--;如果sum<0,那麼說明nums[left]小了,因此left++

1-3為基本的想法,然後在此之上還要有優化,跳過一些不必要的迴圈,還有提前退出(見**)

// 優化2: 當nums[i] > 0 ,那麼nums[i]加上後面的比它大的兩個數肯定也大於0,甚至是後面的數([i+1], [i+2]……)作為起始數時肯定也大於0(陣列已經排過序),

// 因此可以跳過;

// 當 nums[i] + nums[left] + nums[left+1]>0,說明nums[i]與後面的範圍中任取兩個數並且這兩個數是最小值,他們的和都大於0,後面的數([i+1], [i+2]……)作為起始數時sum也大於0,

// 因此也可以跳過;

if (nums[i] > 0 || (nums[i] + nums[left] + nums[left+1])>0)

// 優化3: 當nums[i] + nums[right] + nums[right - 1] < 0時,說明nums[i]與後面的範圍中任取兩個數並且這兩個數是最大值,得到的sum < 0,說明nums[i]這個起始數選小了

// 因此跳過進入下一層迴圈;

if (nums[i] + nums[right] + nums[right - 1] < 0)

while (left < right)

while (left < right && nums[right] == nums[right + 1])

tmp.clear();

tmp.resize(num);

}else

if (sum < 0)

}else

if (sum > 0)}}

}return res;

}以後做題一定要多想想有沒有更好的辦法,還得多注意下能不能優化的。切記切記!

LeetCode 15 三數之和

15.給定乙個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c 使得 a b c 0 找出所有滿足條件且不重複的三元組。注意 答案中不可以包含重複的三元組 方法一,個人解法正確,但是效率太低,時間複雜度o n 3 時間超時,無法提交至leetcode public s...

leetcode 15 三數之和

給定乙個包含 n 個整數的陣列nums,判斷nums中是否存在三個元素 a,b,c 使得 a b c 0 找出所有滿足條件且不重複的三元組。注意 答案中不可以包含重複的三元組。例如,給定陣列 nums 1,0,1,2,1,4 滿足要求的三元組集合為 1,0,1 1,1,2 class solutio...

leetcode15 三數之和

給定乙個包含 n 個整數的陣列nums,判斷nums中是否存在三個元素 a,b,c 使得 a b c 0 找出所有滿足條件且不重複的三元組。注意 答案中不可以包含重複的三元組。例如,給定陣列 nums 1,0,1,2,1,4 滿足要求的三元組集合為 1,0,1 1,1,2 先找兩數之和,然後再用un...