题目描述:【腾讯精选练习(50 题)】
给定一个包含 n 个整数的数组 nums
,判断 nums
中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
解题代码:
/**
* 第一版:超出时间限制
*/
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> result = new ArrayList();
for (int i = 1; i < nums.length - 1; i++) {
int target = 0 - nums[i];
int l = 0;
int r = nums.length - 1;
while (l < r) {
int sum = nums[l] + nums[r];
if (sum < target) {
l++;
} else if (sum > target) {
r--;
} else {
List<Integer> list = new ArrayList();
list.add(nums[l]);
list.add(nums[i]);
list.add(nums[r]);
if (!result.contains(list)) {
result.add(list);
}
l++;
r--;
}
}
}
return result;
}
}
/**
* 第二版:代码优化后
* 思路分析
* 1. 0多于3个,则结果必有[0,0,0]
* 2. 存在0,则结果必有形式[-a,0,a],单边找
* 3. 不考虑零,则结果只能为[a,a,b]或[a,b,c]。[a,a,b]时,有2a=-b,[a,b,c]时,有a+b=-c。双边找
*/
public static List<List<Integer>> threeSum(int[] nums) {
// 判断数组元素是否少于3个
if (nums.length < 3) {
return new ArrayList();
}
// 对数组元素进行排序
Arrays.sort(nums);
// 声明结果集
List<List<Integer>> result = new ArrayList();
for (int i = 0; i < nums.length - 2; i++) {
// 通过set进行去重
// Set<Integer> set = new TreeSet();
// for (int i : nums) {
// set.add(i);
// }
// set转换为数组
// Integer[] arr = {};
// arr = set.toArray(arr);
// 数组转换为list
// String[] str = {"a","b","c"};
// List list = Arrays.asList(str);
// list转换为数组
// ArrayList<String> list = new ArrayList<String>();
// String[] str = new String[list.size()];
// list.toArray(str);
// skip duplicate
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
if (nums[i] < 0) {
// 初始化指针
int l = i + 1;
int r = nums.length - 1;
// 计算target值
int target = 0 - nums[i];
while (l < r) {
if (nums[l] + nums[r] < target) {
l++;
} else if (nums[l] + nums[r] > target) {
r--;
} else {
// 避免重复添加相同list。需要判断r == nums.length - 1,避免r + 1数组越界,l - 1则不会数组越界。
if (nums[l] != nums[l - 1] || r == nums.length - 1 || nums[r] != nums[r + 1]) {
List<Integer> list = new ArrayList();
list.add(nums[i]);
list.add(nums[l]);
list.add(nums[r]);
// 对list进行排序,效率低
// Collections.sort(list);
// Collections.sort(list, new Comparator<Integer>() {
// @Override
// public int compare(Integer o1, Integer o2) {
// return o2 - o1;
// }
// });
result.add(list);
}
l++;
r--;
}
}
} else if (nums[i] == 0) {
int count = 0;
for (int j = i + 1; j < nums.length; j++) {
if (nums[j] == 0) {
count++;
}
if (count == 2) {
// 将int数组转为list
// int[] arr = {0, 0, 0};
// List<int[]> list = Arrays.asList(arr);
// 将Integer数组转为list
List<Integer> list = Arrays.asList(0, 0, 0);
// 判断是否重复添加,效率低
if (!result.contains(list)) {
result.add(list);
}
break;
}
}
}
}
return result;
}