LeetCode——15. 三数之和(C++)

题目链接:https://leetcode-cn.com/problems/3sum/

#include <bits/stdc++.h>
using namespace std;

/*
努力优化后的 排序+for循环,结果依旧逃不过超时的厄运
*/
//class Solution
//{
//  public:
//    vector<vector<int>> threeSum(vector<int>& nums)
//    {
//      sort(nums.begin(), nums.end());
//      vector<vector<int>> res;
//      int len = nums.size();
//      for(int i = 0; i < len - 2; i++)
//      {
//        if(nums[i] > 0) break;
//        if(nums[i] * 2 > 0) break;
//        if(nums[i] * 3 > 0) break;
//        if(i != 0 && nums[i - 1] == nums[i]) continue; // i 变化之后,位置上的值未变,则继续变 i
//        for(int j = i + 1; j < len - 1; j++)
//        {
//          if(nums[i] + nums[j] > 0) break;
//          if(nums[i] + nums[j] * 2 > 0) break;
//          if(j != i + 1 && nums[j - 1] == nums[j]) continue;  // 在 i 不变的情况下,如果 j 位置的值也没有变,则没必要进一步进行
//          int flag = 0 - nums[i] - nums[j];
//          for(int k = j + 1; k < len; k++)
//          {
//            if(k != j + 1 && nums[k - 1] == nums[k]) continue;  // k 变化之后,位置上的值未变,则继续变 k
//            if(nums[k] > flag) break;
//            if(nums[k] == flag)
//            {
//              vector<int> v = {nums[i], nums[j], nums[k]};
//              res.push_back(v);
//              break;
//            }
//          }
//        }
//      }
//      return res;
//    }
//};

/*
优化版:排序+双指针
*/
class Solution
{
  public:
    vector<vector<int>> threeSum(vector<int>& nums)
    {
      vector<vector<int>> res;
      int len = nums.size();
      if(len < 3) return res;
      sort(nums.begin(), nums.end());
      for(int i = 0; i < len - 2; i++)
      {
        if(nums[i] > 0) return res;
        int l = i + 1;
        int r = len - 1;
        while(l < r)
        {
          // 网友提供的思路,要考虑溢出
          long long x = static_cast<long long>(nums[i]);
          long long y = static_cast<long long>(nums[l]);
          long long z = static_cast<long long>(nums[r]);

          if(x + y + z > 0) r--;
          else if(x + y + z < 0) l++;
          else if(x + y + z == 0)
          {
            vector<int> v = {nums[i], nums[l], nums[r]};
            res.push_back(v);
            while(l < r && nums[l] == nums[l + 1]) l++;
            while(l < r && nums[r] == nums[r - 1]) r--;
            l++;
            r--;
          }
        }
        while(i + 1 < len - 2 && nums[i] == nums[i + 1]) i++;
      }
      return res;
    }
};

int main()
{
  Solution sol;
//  vector<int> v0 = {-1, 0, 1, 2, -1, -4};
//  vector<int> v0 = {0,0,0,0};
//  vector<int> v0 = {0,0,0};
  vector<int> v0 = {-4,-1,-4,0,2,-2,-4,-3,2,-3,2,3,3,-4};
  vector<vector<int>> res = sol.threeSum(v0);
  for(int i = 0; i < res.size(); i++)
  {
    for(int j = 0; j < 3; j++)
    {
      cout<<res[i][j]<<" ";
    }
    cout<<endl;
  }
  cout<<endl;
  return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我有明珠一颗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值