【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;
 }
};

启发是对数组进行排序,就可以根据和来调整左右指针了,并且对正值后面都不用判断了省了不少时间!

发布了7 篇原创文章 · 获赞 4 · 访问量 180

猜你喜欢

转载自blog.csdn.net/fengshiyu1997/article/details/104660192