给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
题目清晰,方法也很容易想出,先排序数组,拿一个指针作桩,再用两个指针进行寻找
这里有三个可以优化的地方:
- 当指定一个数为桩,只要找他右边的数即可,因为左边的数的可能性之前已经完成了
- 当数组里面全是相同符号的数,就可以不用在找了
- 当桩到数组末尾全是相同符号的数,也可以不要再找了
这里的"桩"就是一个指针,如图绿色箭头所指,然后再创建出两个新的指针,根据当前
所得出的三数和,来判断下一步该干嘛
public static List<List<Integer>> threeSum(int[] nums) { Set<List<Integer>> resultSet = new LinkedHashSet<>(); List<Integer> list = new LinkedList<>(); List<List<Integer>> resultList = new LinkedList<>(); int length = nums.length; if (length < 3) { return resultList; } Arrays.sort(nums); if (nums[0] <= 0 && nums[length - 1] >= 0) { for (int i = 0; i < length - 1; i++) { if (nums[i] > 0) { break; } int first = i + 1; int last = length - 1; while (first < last) { if ((long)nums[i] * nums[last] > 0) {//着重注意一下这里 break; } long res = nums[i] + nums[first] + nums[last]; if (res == 0) { list = new LinkedList<>(); list.add(nums[i]); list.add(nums[first]); list.add(nums[last]); resultSet.add(list); } if (res <= 0) { first++; } else { last--; } } } } Iterator<List<Integer>> setIt = resultSet.iterator(); while(setIt.hasNext()){ resultList.add(setIt.next()); } return resultList; }