LeetCode:3Sum, 3Sum Closest, 4Sum

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)

Subscribe to see which companies asked this question

  • 分析:最简单的思路应该是O(n^3)也就是暴力求解:三重for循环计算出每三个字组合的结果与目标,作为一个志向的程少年我们显然不能满足于这种方法,仔细思考下有没有其他的解决办法。有没有可能把时间复杂度压缩到O(n^2)。
  • 我们把数进行下排列成为有序数列:排序的时间复杂度为O(nlgn)<O(n^2),分析排序后的数列。
  • 1,2,3,4,5,6,7  可以直观想到两个数的和最大值和最小值分别为8和3,对应位置为(6+7)和(1+2)定义两个指针分别从指向头i和尾j,例如查找和为9,的两个数开始时候1+7=8<9 ,这时候我们需要一个大一点的数,头指针就往后一个i+1指向2,(2+7=9)存入一个结果,这时候头尾各向相对方向前进一步,注意人(如果当前a[i]=a[i+1]),i单独向后走,同理j单独向前走)。
  • 我们可以把这个问题推广下对于3nums 就是固定一个数找2num,对于4nums,就是固定一个数找3nums,以此类推,这类问题都可以同一解了。
  • 代码如下
    </pre><pre name="code" class="cpp">class Solution {
    public:
    	vector<vector<int>>  answer;
    	void find(vector<int>& nums,int begin,int end,int target){
    		int i = begin,j = end;
    		while(i<j){
    			if(nums[i] + nums[j] + target == 0){
    			vector<int> ans ;
    			ans.push_back(target);
    			ans.push_back(nums[i]);
    			ans.push_back(nums[j]);
    			answer.push_back(ans);
    			while(i<j && nums[i] == nums[i+1]) i++;
    			while(i<j && nums[j] == nums[j-1]) j--;
    				i++;
    				j--;
    			}else if (nums[i] + nums[j] + target<0){
    				i++;
    			}else if (nums[i] + nums[j] + target>0){
    				j--;
    			}
    		}
    
    }
    
        vector<vector<int>> threeSum(vector<int>& nums) {
    		
    		sort(nums.begin(),nums.end());
    		if (nums.size()<3 )
    			return answer;
    		sort(nums.begin(),nums.end());
    		int len =nums.size();
    		for(int i = 0 ;i<len-2;i++){
    			if(i>=1){
    			if(i<len &&nums[i] == nums[i-1]){
    				continue;
    
    			}
    			}
    			find(nums,i+1,len-1,nums[i]);
    		}
            
            return answer;
        }
    };
    

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值