LeetCode: 3Sum

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

Note:

  • Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
  • 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)
#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
using namespace::std;

class Solution {
public:
	long RSHash(string str)
	{
		int a = 378551;
		int b = 63689;
		long hash = 0;
		for(int i = 0; i < str.size(); i++)
		{
			hash = hash * a + str[i];
			a = a * b;
		}
		return hash;
	}
    vector<vector<int> > threeSum(vector<int> &num) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        vector< vector<int> > result;
		int tmp = 0;
		int flag = 0;
		int a = 0, b = 0, c = 0;
		long hash;
		string str;
		vector<int> set;
		map<long, int> mymap;
		if(num.size() < 3)
			return result;
		sort(num.begin(), num.end());
			for(int x = 0; x < num.size() - 2; x++)
			{
				a = num[x];
				for(int i = x + 1, j = num.size() - 1; i < j; )
				{
					b = num[i];
					c = num[j];
					if(a + b + c < 0)
						i++;
					else if(a + b + c > 0)
						j--;
					else
					{
						str.clear();
						str += a;
						str += b;
						str += c;
						hash = RSHash(str);
						if(mymap.find(hash) == mymap.end())
						{
							mymap[hash] = 1;
							set.push_back(a);
							set.push_back(b);
							set.push_back(c);
							result.push_back(set);
							set.clear();
						}
						i++;

					}
				}
					
							
							
					
			}
			return result;

    }
	void print(vector< vector<int> > & result)
	{
		cout<<"size: "<<result.size()<<endl; 
		for(int i = 0; i < result.size(); i++)
		{
			for(int j = 0; j < result[i].size(); j++)
			{
				cout<<result[i][j]<<" ";
			}
			cout<<endl;
		}

	}
};

int main()
{
	vector<int> aa;
	
	aa.push_back(-1);
	aa.push_back(0);
	aa.push_back(1);
	aa.push_back(2);
	
	aa.push_back(-1);
	
	aa.push_back(-4);
	
	Solution ss;
	ss.threeSum(aa);
	ss.print(ss.threeSum(aa));
}

解法2: 此法在解决重复问题上没有使用hash,较为简单

class Solution {
public:
    vector<vector<int> > threeSum(vector<int> &num) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        vector<vector<int> > output;
        if(num.size()<3) return output;
        sort(num.begin(),num.end());
        int i=0,j,k,n;
        n=num.size();
        while(i<n){
            if(num[i] > 0){//no solution
                break;
            }
            int temp = 0 - num[i];
            j = i+1;
            k = n-1;
            while(j<k){
                int sum2 = num[j] + num[k];
                if(sum2 == temp){//found one triplet
                    vector<int> triplet;
                    triplet.push_back(num[i]);
                    triplet.push_back(num[j]);
                    triplet.push_back(num[k]);
                    output.push_back(triplet);
                    //Be careful, we want to skip all the duplicate numbers, 
                    //so that no duplicate triplets are recorded
                    j++;
                    while(j<k && num[j-1] == num[j]) j++;
                    k--;
                    while(k>j && num[k+1] == num[k]) k--;
                }
                else if(sum2 > temp){
                    k--;
                    while(k>j && num[k+1] == num[k]) k--;
                }
                else{
                    j++;
                    while(j<k && num[j-1] == num[j]) j++;
                }
            }
            i++;
            while(i<n && num[i-1] == num[i]) i++;
        }
        return output;
    }
};


学习点:1. 在O(n^2)时间内解决3 Sum 问题http://en.wikipedia.org/wiki/3SUM
What I learned:
Round 2:
class Solution {
public:
    vector<vector<int> > threeSum(vector<int> &num) {
        std::sort(num.begin(), num.end());
        vector<vector<int> > result;
        if(num.size() < 3)
            return result;
        vector<int> temp;
        for(int i = 0; i < num.size()-2; i++)
        {
            int l = i+1, r = num.size()-1;
            while(l < r)
            {
                if(num[i] + num[l] + num[r] == 0)
                {
                    temp.clear();
                    temp.push_back(num[i]);
                    temp.push_back(num[l]);
                    temp.push_back(num[r]);
                    result.push_back(temp);
                    l++;
                    r--;
                    while(l < r && num[l] == num[l-1])
                        l++;
                }
                else if(num[i] + num[l] + num[r] > 0)
                {
                    r--;
                }
                else
                    l++;
            }
            while(i+1 < num.size()-2 && num[i] == num[i+1])
                i++;
        }
        return result;
    }
};


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值