LeetCode #15 - 3Sum

题目描述:

Given an array S of n integers, are there elements a,b,c inS such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note: The solution set must not contain duplicate triplets.

For example, given array S = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]
简单翻译就是找出数组中存在的三个不相同数的所有组合使得这三个数之和为0,并且保证所有组合不重复。

这道题的方法可以先给数组排序,再确定三个数中最小的数nums[i],然后使用两个指针j=i+1、k=n-1,从两头搜索,这样可以减少搜索次数,确定另外两个数使得这三个数之和为0,即为满足条件的组合。本题最大的难点在于保证组合不重复,因此采取以下方法:

一、先确定的数为nums[i],另外确定的数为nums[j]、nums[k],在保证i<j<k时才将这三个数push到结果向量中,可以避免nums[i]、nums[j]、nums[j]更换顺序导致重复。

二、在数组中可能存在多个值相同的数,为了避免nums[j]、nums[j]、nums[i]这三个数与值相同的其他数重复,可以分情况讨论:①避免nums[i]重复:如果i>0且nums[i]=nums[i-1]则i++;②避免nums[j]、nums[k]重复,如果nums[j]=nums[j-1]且j<k,则j++;如果nums[k]=nums[k+1]且k>j,则k--。


class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        vector<vector<int> > result;
        if(nums.size()<3) return result;
        for(int i=0;i<nums.size()-2;i++)
        {
            int n=nums.size();
            while(nums[i]==nums[i-1]&&i>0) i++;
            int j=i+1;
            int k=n-1;
            while(j<k)
            {
                if((nums[i]+nums[j]+nums[k])<0) j++;
                else if((nums[i]+nums[j]+nums[k])>0) k--;
                else if((nums[i]+nums[j]+nums[k])==0) 
                {
                    vector<int> temp;
                    temp.push_back(nums[i]);
                    temp.push_back(nums[j]);
                    temp.push_back(nums[k]);
                    result.push_back(temp);
                    j++;
                    k--;
                    while(nums[j]==nums[j-1]&&j<k) j++;
                    while(nums[k]==nums[k+1]&&k>j) k--;
                }
            }
        }
        return result;
    }
};

由于多次判断使指针跳过重复的数值比较繁琐,而且容易出错,可以直接使用集合,重复的向量无法插入集合中,所以不用额外去判断重复值,使代码更加简单。

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        set<vector<int> > result_set;
        vector<vector<int> > result_vec;
        if(nums.size()<3) return result_vec;
        for(int i=0;i<nums.size()-2;i++)
        {
            int n=nums.size();
            int j=i+1;
            int k=n-1;
            while(j<k)
            {
                if((nums[i]+nums[j]+nums[k])<0) j++;
                else if((nums[i]+nums[j]+nums[k])>0) k--;
                else if((nums[i]+nums[j]+nums[k])==0) 
                {
                    vector<int> temp;
                    temp.push_back(nums[i]);
                    temp.push_back(nums[j]);
                    temp.push_back(nums[k]);
                    result_set.insert(temp);
                    j++;
                    k--;
                }
            }
        }
        
        for(set<vector<int> >::iterator it=result_set.begin();it!=result_set.end();it++)
            result_vec.push_back(*it);
        return result_vec;
    }
};



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值