本類題可分為兩類,一種是利用雜湊表直接進行查詢,另一種是利用雙指標進行雙向查詢。
力扣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 請你找出所有滿足條件且不重複的三元組。注意 答案中不可以包含重複的三元組。解題思路 為防止有重複三元組的情況,首先把陣列排序。對於找三元組,可以使用暴力求解的方法,但如果對執行時...