LeetCode题目:四数之和

题目描述:

给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。
注意:
答案中不可以包含重复的四元组。
示例:
给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。
满足要求的四元组集合为:
[[-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2]]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/4sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

四数之和其实和三数之和的思路差不多,定义一个外循环,循环遍历排列后的数组除了最后3个的其他元素,循环体里面就是一个三数之和了,区别在于sum是四个元素的相加。另外,还可以考虑每一层的循环中能达到的最小最大值,和target做比较,如果该层中的最小最大值分别大于和小于target,那就可以直接跳过这一层了,以此来减少迭代的次数。

代码(Java):

public class Redo {
	public static void main(String[] args) {
		int[] nums = new int[] {-1,0,1,2,-1,-4};
		int target = -1;
		System.out.println(fourSum(nums, target));
	}
	
	public static List<List<Integer>> fourSum(int[] nums,int target){
		List<List<Integer>> ans = new ArrayList<List<Integer>>();
		if(nums==null || nums.length<4) return ans;
		Arrays.sort(nums);
		int length = nums.length;
		for(int h = 0;h<length-3;h++) {
			if(h>0 && nums[h]==nums[h-1]) continue; //这个数字出现在这一位(第一位)的情况已经有了,跳过
			int min1 = nums[h]+nums[h+1]+nums[h+2]+nums[h+3]; //这个是h这个循环中能达到的最小值
			if(min1>target) {//如果这个最小值都比target大,那就没有值等于target的了,直接结束
				break;
			}
			int max1 = nums[h]+nums[length-1]+nums[length-2]+nums[length-3]; //这个是h这个循环中能达到的最大值
			System.out.println(max1);
			if(max1<target) {//如果这个最小值都比target小,那就没有值等于target的了,直接跳过
				continue;
			}
			for(int i = h+1;i<length-2;i++) {
				if(i>h+1 && nums[i]==nums[i-1]) continue;//这个数字出现在这一位(第二位)的情况已经有了,跳过
				int j = i+1;
				int k = length-1;
				int min2 = nums[h]+nums[i]+nums[j]+nums[j+1];//这个是i这个循环中能达到的最小值
				if(min2>target) {//如果这个最小值都比target大,那就没有值等于target的了,直接跳过
					continue;
				}
				int max2 = nums[h]+nums[i]+nums[k]+nums[k-1];//这个是i这个循环中能达到的最大值
				if(max2<target) {//如果这个最小值都比target小,那就没有值等于target的了,直接跳过
					continue;
				}
				while(j<k) {
					int sum = nums[h]+nums[i]+nums[j]+nums[k];
					if(sum==target) {
						ans.add(Arrays.asList(nums[h],nums[i],nums[j],nums[k]));
						j++;
						while(j<k && nums[j]==nums[j-1]) j++;
						k--;
						while(j<k && nums[k]==nums[k+1]) k--;
					}
					else if(sum>target) k--;
					else if(sum<target) j++;
				}
			}
			
		}
		return ans;
	}
发布了0 篇原创文章 · 获赞 0 · 访问量 82

猜你喜欢

转载自blog.csdn.net/weixin_43556670/article/details/105695507