Java算法题-解析 "四数之和" 算法问题
题目:
给定一个包含 n 个整数的数组 nums
和一个目标整数 target
,要求找到数组中四个元素,使得它们的和等于目标整数 target
。返回所有满足条件的不重复四元组。
引言:
"四数之和" 是一个数组处理问题,要求在数组中找到满足和为目标值的四个元素。解决这个问题需要对数组操作、双指针法和排序有深刻理解,同时也需要注意去重和边界条件的处理。通过解答这个问题,我们可以提升对数组处理、双指针技巧和问题规模的考虑,同时也能拓展对数值逼近问题的思考。
算法思路:
我们可以使用双指针法来解决这个问题。具体思路如下:
- 首先将数组排序,这样可以更方便地进行双指针操作。
- 遍历数组中的前两个数字作为固定的两个数,然后使用双指针法在剩余的区间中寻找另外两个数,使得它们的和等于
target - nums[i] - nums[j]
。 - 在内层循环中,固定两个指针
left
和right
,从j + 1
和数组尾部开始,同时将另两个指针left
和right
设置为数组的首尾。 - 计算当前四个元素的和
sum
,如果sum
等于target
,则将这四个元素加入结果列表。 - 根据
sum
与target
的大小关系,移动left
和right
指针。 - 为避免重复结果,需要在每次加入结果时,判断当前元素是否与前一个元素相同,以及左指针是否右移过重复元素。
代码实现:
以下是使用 Java 实现的 "四数之和" 算法的示例代码:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FourSum {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
int n = nums.length;
for (int i = 0; i < n - 3; i++) {
if (i > 0 && nums[i] == nums[i - 1]) {
continue; // Avoid duplicates
}
for (int j = i + 1; j < n - 2; j++) {
if (j > i + 1 && nums[j] == nums[j - 1]) {
continue; // Avoid duplicates
}
int left = j + 1;
int right = n - 1;
while (left < right) {
int sum = nums[i] + nums[j] + nums[left] + nums[right];
if (sum == target) {
result.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
while (left < right && nums[left] == nums[left + 1]) {
left++; // Avoid duplicates
}
while (left < right && nums[right] == nums[right - 1]) {
right--; // Avoid duplicates
}
left++;
right--;
} else if (sum < target) {
left++;
} else {
right--;
}
}
}
}
return result;
}
}
算法分析:
- 时间复杂度:排序数组需要 O(n * log n) 的时间,双指针操作需要 O(n^3) 的时间,总时间复杂度为 O(n^3)。
- 空间复杂度:需要额外的结果列表来存储符合条件的四元组,所以空间复杂度为 O(n)。
示例和测试:
假设给定数组为 [1,0,-1,0,-2,2]
,目标整数为 0
,根据算法,可以找到不重复的四元组 [-2,-1,1,2]
、[-2,0,0,2]
和 [-1,0,0,1]
。
我们可以使用以下代码进行测试:
import java.util.List;
public class Main {
public static void main(String[] args) {
FourSum solution = new FourSum();
int[] nums = {1, 0, -1, 0, -2, 2};
int target = 0;
List<List<Integer>> result = solution.fourSum(nums, target);
for (List<Integer> quadruplet : result) {
System.out.println(quadruplet);
}
}
}
总结:
"四数之和" 算法问题要求在数组中找到满足和为目标值的不重复四元组,是一个涉及数组处理和双指针技巧的问题。通过实现这个算法,我们可以提升对数组操作、双指针技巧和去重处理的应用,同时也能拓展对问题规模和逼近问题的考虑。这个问题强调了在解决编程难题时,从多个角度考虑问题的重要性,以及如何使用双指针法来处理数组中的多重组合情况。