leetcode -15 3sum

3Sum

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

 

找到一个数组中3个数字。使得3个数字相加等于0

 

方法1On^3

       利用暴力搜索。既然是三个数字,那么在n个数字中选择3个,一共有n(n-1)(n-2)/6种情况(n>2)。复杂度为O(n^3)

 

方法2On*m*longn。)

3个数字相加,一共有3种情况是为0:三个数字都为0;有一个数字为0,另外两个是相反数;三个数字都不为0,

1.    先遍历一遍数组,然后把数组分成两个数组,一个数组中所有元素都小于0,另外一个全都大于等于0,然后排序这个两个数组。

2.    考虑到第一种情况和第二种情况,都至少有一个负数,从负数数组开始遍历,选择一个负数,再从另外一个大于等于0数组从头开始遍历,求得它们的和后判断和是大于等于0还是小于0,然后再利用二分法查找数组。

3.    最后再看看一共有几个0,若超过3个,就追加30进数组。

ps:有个小细节,需要注意就是重复的数字。

 

 

复杂度分析:

假设数组长为N。分成两个数组为,n,m

       第一步需要遍历数组,分成两个部分,然后排序。需要NlongN(近似)。第二步要遍历这两个数组,并查找,为n*m*longn

 

 

方法3On^2

 

       利用之前写到的2SUM来进行加工,因为2SUM的复杂度为O(n),这里只需要将原来的数组排序好后,遍历一次数组,其中数组的每一个元素都是target的值,然后稍微修改一下2SUM就可以。http://blog.csdn.net/laeen/article/details/54570971

class Solution {
public:

vector<int> twoSum(vector<int>& nums, int target , int start) {

        map<int,int> mymap;
		pair <int,int> p;
		
		map<int,int>::iterator it;
		map<int,int>::iterator it1;
		vector<int> v;
		int flag = 0;
		int s = nums.size();
		
		for(int i = start ; i < s ; i++){
			p.first = nums[i];
			p.second = i;
			if(mymap.count(p.first) && flag == 0)
				if(target == 2 * p.first){
					it = mymap.find(p.first);
					v.push_back(-target);
					v.push_back((*it).first);
					v.push_back(p.first);
					flag = 1; //设置标记,若有重复的数字,比如nums为0 0 0 0这样的就会出现三种结果,利用flag可以避免重复
			    		
			}	
			mymap.insert(p);
		}
		
		for(it = mymap.begin(); it != mymap.end(); it++){
			int r = target - (*it).first;		
			it1 = mymap.find(r) ;
			if(it1 != mymap.end() && it1 != it   && (*it).first < (*it1).first){

				v.push_back(-target);
				v.push_back((*it).first);
				v.push_back((*it1).first);	
						
			}
		}
	return v;

}
	
vector< vector<int> > threeSum(vector<int>& nums) {
     	
     	vector< vector<int> > r;
     	vector<int> v;
     	vector<int> n;
     	int count = 0;
     	int before = 1;
		sort(nums.begin(),nums.end());
		
		for(int i = 0 ; i < nums.size() ; i++){
		
			if(before == nums[i]){
				continue; //避免重复的数字
			}
			before = nums[i];
			v.clear();
			v = twoSum(nums,0-nums[i] ,i + 1);
			
			for(int i = 0 ; i < v.size() ; i+=3){
				n.clear();
				for(int k = i ; k < i + 3 ; k++){														
					n.push_back(v[k]);
		
			}
			r.push_back(n);
		}	
	}

   	
     
 	return r;
    	
}
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值