LeetCode18:四数之和
Posted mx_info
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode18:四数之和相关的知识,希望对你有一定的参考价值。
LeetCode18:四数之和
题目描述
/**
* 给定一个包含 n 个整数的数组 nums 和一个目标值 target,
* 判断 nums 中是否存在四个元素 a,b,c 和 d ,
* 使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。
* <p>
* 注意:答案中不可以包含重复的四元组
*/
思路分析
- 使用排序 + 双重遍历 + 双指针的思路
- 使用外层循环从左到右遍历一次数组元素,因为至少要保证四个数求和,因此第一层遍历只需要循环 len - 3次即可
- 使用内层循环从第一次遍历的右一个下标开始遍历,保证数组中所有情况都能考虑到
- 使用排序,可以方便两指针的移动
- 使用左指针指向内层循环的右侧一个元素,右指针指向倒数第一个元素,则可以根据四个数的和与target 的关系移动左右指针
- 因为要求不包含重复元素,则可以使用hash结构去重,将去重后的元素序列添加
- 考虑优化: 可以判断四个数的和 的最大值或者最小值与target的关系,提前结束此次循环
源码及分析
//思路分析
//1. 使用排序 + 双重循环 + 双指针
public List<List<Integer>> fourSum(int[] nums, int target) {
//数据校验:如果nums为空或者长度小于4,返回空
if (nums == null || nums.length < 4) {
return new ArrayList<List<Integer>>();
}
//创建集合保存返回的数字序列
ArrayList<List<Integer>> lists = new ArrayList<>();
//使用hash结构去重
HashSet<List> set = new HashSet<>();
//数组元素排序
Arrays.sort(nums);
int len = nums.length;
//双重循环:外层循环从左到右一次遍历 len - 3次
for (int i = 0; i < len - 3; i++) {
//内层循环从 i 的右侧一位开始遍历,避免重复
for (int j = i + 1; j < len - 2; j++) {
//定义两个指针本别执行j后边元素和最后一个元素
int left = j + 1, right = len - 1;
while (true) {
//如果四个数的和等于target:使用hash结构去重并添加到集合
if (nums[i] + nums[j] + nums[left] + nums[right] == target) {
ArrayList<Integer> list = new ArrayList<>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[left]);
list.add(nums[right]);
if (set.add(list)) {
lists.add(list);
}
left++;
//否则移动左右指针
}
//如果四个数的和大于target
if (nums[i] + nums[j] + nums[left] + nums[right] > target) {
right--;
}
//如果四个数的和小于target
if (nums[i] + nums[j] + nums[left] + nums[right] < target) {
left++;
}
//循环结束条件
if (left == right) {
break;
}
}
}
}
//返回
return lists;
}
以上是关于LeetCode18:四数之和的主要内容,如果未能解决你的问题,请参考以下文章