三数之和
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 220 ms, 内存: 18.6 MB
/*
* 思路:
* 1. 使用Java Stream来简化代码流程。
* 2. 首先对数组进行排序。
* 3. 使用三指针方法,固定一个数,然后在剩余的数组中使用双指针来查找另外两个数。
* 4. 遍历过程中,跳过重复的数以避免重复结果。
*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class ThreeSumStream {
public List<List<Integer>> threeSum(int[] nums) {
if (nums == null || nums.length < 3) return new ArrayList<>();
Arrays.sort(nums); // 对数组进行排序
return Arrays.stream(nums).boxed().flatMap(i -> {
if (i > 0 && nums[i] == nums[i - 1]) return null; // 跳过重复的数
int left = i + 1, right = nums.length - 1;
List<List<Integer>> temp = new ArrayList<>();
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (sum == 0) {
temp.add(Arrays.asList(nums[i], nums[left], nums[right]));
while (left < right && nums[left] == nums[left + 1]) left++; // 跳过重复的数
while (left < right && nums[right] == nums[right - 1]) right--; // 跳过重复的数
left++;
right--;
} else if (sum < 0) {
left++;
} else {
right--;
}
}
return temp.stream();
}).distinct().collect(Collectors.toList());
}
public static void main(String[] args) {
ThreeSumStream solution = new ThreeSumStream();
int[] nums = {-1, 0, 1, 2, -1, -4};
System.out.println(solution.threeSum(nums)); // 输出: [[-1, -1, 2], [-1, 0, 1]]
}
}
解释
方法:
此题解采用排序加双指针的方法解决三数之和问题。首先对数组进行排序,然后使用外层循环遍历每个数作为可能的三元组中的第一个数。对于每个选定的第一个数,使用内层的双指针来查找剩余两个数。如果三个数的和为零,则记录这个组合。为了避免重复的三元组,每次在找到有效的三元组后,需要跳过相同的数。同时,如果当前的数大于0,则可以直接终止循环,因为不可能再找到和为零的三元组。
时间复杂度:
O(n^2)
空间复杂度:
O(1)
代码细节讲解
🦆
为什么在遍历数组的过程中,当遇到第一个数大于0时,可以直接终止循环?
▷🦆
在双指针中,如果左指针和右指针指向的元素和未达到目标值时,为什么只移动左指针而不考虑移动右指针?
▷🦆
在跳过重复数字时,你是如何确保不会漏掉任何有效的三元组解?
▷