【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)

代码

struct node{
    int index;
    int value;
};
bool compile(const struct node &a , const struct node &b)
{
    return a.value < b.value;
}



class Solution {
public:
    vector<vector<int> > threeSum(vector<int> &num) {
		vector<vector<int> > resultv;
		int len = num.size();
		
		vector<struct node> temp(len);
        struct node n;
        for (int i = 0 ; i < len ; i ++) {
            n.index = i+1; n.value = num[i];
            temp[i] = n;
        }
        
		sort(temp.begin() , temp.end() , compile);
		
        int i = 0;
		
		for ( i = 0 ; i < len ; i++) {
			int target = 0 - temp[i].value;
			//cout<<target<<","<<temp[i].value<<endl;
			int j =0;
			int k =0;
			for (j = i+1  ,k = len-1; j < k; ) {
				if (j == i) {
					j++;
					continue;
				}
				if (k == i) {
					k--;
					continue;
				}
				
				//cout<<"sum:"<<temp[j].value << "+ "<< temp[k].value<<endl;
				if (temp[j].value + temp[k].value < target) {
					j++;
				}
				else if(temp[j].value + temp[k].value > target)
				{
					k--;
				}
				else
				{
					/* equal */
					
					vector<int> group;
					group.push_back(temp[i].value);
					group.push_back(temp[j].value);
					group.push_back(temp[k].value);

					resultv.push_back(group);
					
					int tempk = temp[k].value;
					int tempi = temp[i].value;
					int tempj = temp[j].value;
					
					while (tempk == temp[k].value && k > j) {
						k--;
					}
					
					while (tempj == temp[j].value && j < k) {
						j++;
					}
					
					while (tempi == temp[i].value && i< len) {
						i++;
					}
					i--;
					//break;
				}
			}
		}
		
		
		
		return resultv;
    }
};

分析

首先先排序,复杂度O(nlogn);

其次 遍历整个数组,每次确定一个数,假设为a,则其他两个数的和是  ( 0-a) ,(O(N))

再次,按照2sum 的算法找到 (0-a), O(N).

最后,跳过重复的元素。总的复杂度是 O(O^2) + O(NLOGN) = O(N^2)


分析2:

这里还有第二种解法:

1. hash表,i,j遍历一遍,算出所有两两相加的值,并存到hash表中,时间复杂度是O(N^2),控件复杂度也是 n^2。

2. 遍历一遍,利用hash表查找 (0-a) 是否存在,复杂度是 O(N^2) , 和上面一样,不过有些空间上的损失。

这里可以思考得出一个结论,hash表这种算法,可以导出 4sum 的算法复杂度也可以是 O(N^2)。下一篇博文将实现这个算法。

 总结

2sum的一种变形。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值