【leetcode 刷題日記】04-三數之和

三數之和

題目鏈接三數之和

兩數之和思路

這道題我們先想兩數之和怎麼做呢?兩數相加等於0,兩重for循環暴力解答。怎麼樣可以更快一點呢?可以用哈希把時間複雜度從O(n^2)轉爲O(n)。先把每個元素想要的target值存入哈希表中,複雜度爲O(n),再用一個O(n)的時間複雜度從哈希表中查找即可。

三數之和思路

還是運用雙指針的思想,這回不是快慢指針的思想了。

  1. 首先考慮數組長度小於3的,直接返回null
  2. 對數組進行排序
  3. 遍歷排序後的數組
    當前nums[i]>0,後面的數就都大於0了,於是直接break;
    跳過重複元素,避免重複解
    令左指針=i+1,右指針=n-1,在L<R的情況下進行循環
    nums[i]+nums[L]+nums[R]==0時,判斷L++和R–是否和之前的一樣,不同的話就返回
    如果nums[i]+nums[L]+nums[R]>0,則右指針的值太大,R–
    如果nums[i]+nums[L]+nums[R]<0,則左指針的值太小,L++
class Solution {
public:
 vector<vector<int>> threeSum(vector<int>& nums) {
  vector<vector<int>> ans;
  if (nums.size()<3) return ans;
  sort(nums.begin(), nums.end());
  if (nums[0]>0) return ans;
  int i = 0;
  while (i<nums.size()) {
   int left = i + 1, right = nums.size() - 1;
   while (left< right) {
    if (nums[i]>0) break;
    // 轉換爲long long避免加法過程中溢出
    long long y = static_cast<long long>(nums[i]);
    long long x = static_cast<long long>(nums[left]);
    long long z = static_cast<long long>(nums[right]);
    if (x + y >0 - z)
     right--;
    else if (x + y <0 - z)
     left++;
    else {
     ans.push_back({ nums[i], nums[left], nums[right] });
     // 相同的left和right不應該再次出現,因此跳過
     while (left<right&&nums[left] == nums[left + 1])
      left++;
     while (left<right&&nums[right] == nums[right - 1])
      right--;
     left++;
     right--;
    }
   }
   // 避免nums[i]作爲第一個數重複出現
   while (i + 1<nums.size() && nums[i] == nums[i + 1])
    i++;
   i++;
  }
  return ans;
 }
};

啓發是對數組進行排序,就可以根據和來調整左右指針了,並且對正值後面都不用判斷了省了不少時間!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章