N數之和(力扣 二三四數之和總結)

2022-09-24 12:51:07 字數 3265 閱讀 4930

本類題可分為兩類,一種是利用雜湊表直接進行查詢,另一種是利用雙指標進行雙向查詢。

力扣01.兩數之和

力扣454.四數相加

需要利用雜湊表時的題目特徵:

1,多個數不來自於同乙個陣列,這樣不需要考慮同一陣列中重複選擇數字的問題。

2,如果數字是來自同乙個陣列,那麼不超過兩個。

由於利用雜湊表時是借助其鍵值對 key 的值進行查詢,因此通常使用 target - nums[ i ] 的方式進行,這就限定了運算元只能有兩個。

力扣15.三數之和

力扣18.四數之和

雙指標可以將暴力搜尋的 o(n2 ) 複雜度降到 o(n) 。

那麼使用雙指標的入手思路和暴力解法應該是一樣的,只是能減少暴力解法的一層時間複雜度。

注意:如果時間複雜度不超,應該先對陣列進行排序 o(nlog n)。

以四數相加為例:力扣454.四數相加

題目介紹:給定四個包含整數的陣列列表 a , b , c , d ,計算有多少個元組 (i, j, k, l) ,使得 a[i] + b[j] + c[k] + d[l] = 0。

思路:此時 target 的值為 0 是提前確定好的,而 a , b , c , d 均是不同的陣列,這顯然用雜湊法。上面也說了,雜湊法的運算元只能有兩個,因此我們需要提前給 a , b , c , d 分組

class solution 

}int count = 0; // 統計a+b+c+d = 0 出現的次數

// 在遍歷大c和大d陣列,找到如果 0-(c+d) 在map**現過的話,就把map中key對應的value也就是出現次數統計出來。

for (int c : c) }}

return count;

}};

以四數之和為例:力扣18.四數之和

題目介紹:給定乙個包含 n 個整數的陣列 nums 和乙個目標值 target,判斷 nums 中是否存在四個元素 a,b,c 和 d ,使得 a + b + c + d 的值與 target 相等?找出所有滿足條件且不重複的四元組。

思路:由於a, b, c, d 均在同一陣列中,我們只能考慮雙指標簡化暴力解法。但是要注意,每層迴圈都要有判斷是否重複減少比較次數的考慮。

1,準備工作

vector> quadruplets;    // 答案陣列

if (nums.size() < 4)

sort(nums.begin(), nums.end()); // 雙指標必須排序

int length = nums.size();

2,第一重迴圈
for (int i = 0; i < length - 3; i++)
if (i > 0 && nums[i] == nums[i - 1])
if ((long) nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) 

if ((long) nums[i] + nums[length - 3] + nums[length - 2] + nums[length - 1] < target)

3,第二重迴圈

第二重迴圈是巢狀在第一重迴圈裡面,而且迴圈體的內容也基本一致。

if (j > i + 1 && nums[j] == nums[j - 1]) 

if ((long) nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target)

if ((long) nums[i] + nums[j] + nums[length - 2] + nums[length - 1] < target)

4,雙指標部分

雙指標部分是巢狀在第二重迴圈裡面。

int left = j + 1, right = length - 1;

while (left < right)

while (left < right) );

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

left++;

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

right--;

} else if (sum < target)

else

}

5,完整**
class solution 

sort(nums.begin(), nums.end());

int length = nums.size();

for (int i = 0; i < length - 3; i++)

if ((long) nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target)

if ((long) nums[i] + nums[length - 3] + nums[length - 2] + nums[length - 1] < target)

for (int j = i + 1; j < length - 2; j++)

if ((long) nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target)

if ((long) nums[i] + nums[j] + nums[length - 2] + nums[length - 1] < target)

int left = j + 1, right = length - 1;

while (left < right) );

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

left++;

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

right--;

} else if (sum < target) else }}

}return quadruplets;

}};

兩數之和 力扣

這是我寫的第一篇部落格,以前也有過想法,但是總是懶惰,昨晚正好開始刷力扣,就用部落格全程記錄一下吧。刷的第一道題目是兩數之和,題目是這樣的 給定乙個整數陣列 nums 和乙個目標值 target,請你在該陣列中找出和為目標值的那 兩個 整數,並返回他們的陣列下標。你可以假設每種輸入只會對應乙個答案。...

力扣 兩數之和

給定乙個整數陣列 nums 和乙個目標值 target,請你在該陣列中找出和為目標值的那 兩個 整數,並返回他們的陣列下標。你可以假設每種輸入只會對應乙個答案。但是,陣列中同乙個元素不能使用兩遍。示例 給定 nums 2,7,11,15 target 9 因為 nums 0 nums 1 2 7 9...

力扣 三數之和

題目描述 給你乙個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c 使得 a b c 0 請你找出所有滿足條件且不重複的三元組。注意 答案中不可以包含重複的三元組。解題思路 為防止有重複三元組的情況,首先把陣列排序。對於找三元組,可以使用暴力求解的方法,但如果對執行時...