4 Sum

本文探讨了如何寻找数组中四个元素之和等于特定目标值的所有唯一组合,并提供了两种实现方法。第一种方法使用三个循环进行遍历,第二种方法则采用两数之和逐步扩展到四数之和的方式,避免重复并确保解集不包含重复的四元组。

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

Note: The solution set must not contain duplicate quadruplets.

For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0.

A solution set is:
[
  [-1,  0, 0, 1],
  [-2, -1, 1, 2],
  [-2,  0, 0, 2]
]
有两种方法:一种是通过三个循环求解;另一种是用两位数的和,推到三位数的和,再推至四位数的和。

代码一:

public List<List<Integer>> fourSum2(int[] num,int target){
		ArrayList<List<Integer>> ans = new ArrayList<>();
		if(num.length<4)
			return ans;
		Arrays.sort(num);
		
		for(int i=0;i<num.length-3;i++){
			if(i>0 && num[i]==num[i-1])
				continue;
			for(int j=i+1;j<num.length-2;j++){
				if(j>i+1 && num[j]==num[j-1])
					continue;
				int low=j+1,high=num.length-1;
				while(low<high){
					int sum = num[i]+num[j]+num[low]+num[high];
					if(sum==target){
						ans.add(Arrays.asList(num[i],num[j],num[low],num[high]));
						while(low<high && num[low]==num[low+1])
							low++;
						while(low<high && num[high]==num[high-1])
							high--;
						low++;
						high--;
					}else if(sum<target){
						low++;
					}else{
						high--;
					}
				}
			}
		}
		return ans;		
	}

代码二:

public List<List<Integer>> fourSum(int[] nums, int target) {
        ArrayList<List<Integer>> ans = new ArrayList<>();
        if(nums == null || nums.length<4)
            return ans;
        Arrays.sort(nums);
        
        int max = nums[nums.length-1];
        if(4*nums[0] > target || 4*max<target)
            return ans;
        for(int i=0;i<nums.length-3;i++){
            int z = nums[i];
            if(i>0 && nums[i]==nums[i-1])
                continue;
            if(z+3*max <target)
                continue;
            if(4*max<target)
                break;
            if(4*max==target){
                if(i+3<nums.length && nums[i+3]==z){
                    ans.add(Arrays.asList(z,z,z,z));
                }
                break;
            }
            threeSumForFourSum(nums,target-z,i+1,nums.length-1,ans,z);
        }
        return ans;
    }
    
    public void threeSumForFourSum(int[] nums,int target,int low,int high,ArrayList<List<Integer>> ans,int z1){
        if(low+1>=high)
            return;
        int max = nums[high];
        
        if(3*nums[low]>target || 3*max<target)
            return;
        
        for(int i=low;i<high-1;i++){
            int z=nums[i];
            if(i>low && nums[i]==nums[i-1]){
                continue;
            }
            if(z+2*max<target){
                continue;
            }
            if(3*z>target){
                break;
            }
            if(3*z==target){
                if(i+1<high && nums[i+2]==z){
                    ans.add(Arrays.asList(z1,z,z,z));
                }
                break;
            }
                    
            twoSumForFourSum(nums,target-z,i+1,high,ans,z1,z);
        }
    }
    
    public void twoSumForFourSum(int[] nums,int target,int low,int high,ArrayList<List<Integer>> ans,int z1,int z2){
        if(low>=high)
            return;
        if(2*nums[low]>target || 2*nums[high] < target){
            return;
        }
        
        while(low<high){
            int sum=nums[low]+nums[high];
            if(sum == target){
                ans.add(Arrays.asList(z1,z2,low,high));
                
                while(low<high && nums[low]==nums[low+1])
                    low++;
                while(low<high && nums[high]==nums[high-1])
                    high--;
            }else if(sum > target){
                high--;
            }else{
                low++;
            }
        }
        return;
    }






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值