题目

三数之和 - 图1

解题思路

双指针法。

首先,对输入的数组进行排序。

(循环遍历)然后首尾各一个指针,然后再设置一个”机动指针“ 用于从<除了首尾的其他数字>的首尾不断后移,直到找到所有和为0的组合

三数之和 - 图2

代码

  1. class Solution {
  2. public List<List<Integer>> threeSum(int[] nums) {
  3. int n = nums.length;
  4. Arrays.sort(nums);
  5. List<List<Integer>> ans = new ArrayList<List<Integer>>();
  6. // 枚举 a
  7. for (int first = 0; first < n; ++first) {
  8. // 需要和上一次枚举的数不相同
  9. if (first > 0 && nums[first] == nums[first - 1]) {
  10. continue;
  11. }
  12. // c 对应的指针初始指向数组的最右端
  13. int third = n - 1;
  14. int target = -nums[first];
  15. // 枚举 b
  16. for (int second = first + 1; second < n; ++second) {
  17. // 需要和上一次枚举的数不相同
  18. if (second > first + 1 && nums[second] == nums[second - 1]) {
  19. continue;
  20. }
  21. // 需要保证 b 的指针在 c 的指针的左侧
  22. while (second < third && nums[second] + nums[third] > target) {
  23. --third;
  24. }
  25. // 如果指针重合,随着 b 后续的增加
  26. // 就不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环
  27. if (second == third) {
  28. break;
  29. }
  30. if (nums[second] + nums[third] == target) {
  31. List<Integer> list = new ArrayList<Integer>();
  32. list.add(nums[first]);
  33. list.add(nums[second]);
  34. list.add(nums[third]);
  35. ans.add(list);
  36. }
  37. }
  38. }
  39. return ans;
  40. }
  41. }