https://leetcode-cn.com/problems/3sum/

    1. class Solution {
    2. public List<List<Integer>> threeSum(int[] nums) {
    3. List<List<Integer>> resList = new ArrayList<>();
    4. if (nums == null || nums.length == 1 || nums.length == 2) {
    5. return resList;
    6. }
    7. Arrays.sort(nums);
    8. for (int i = 0; i < nums.length - 2; i++) {
    9. if (nums[i] > 0) break;
    10. if (i >= 1 && nums[i] == nums[i - 1]) continue;
    11. int left = i + 1;
    12. int right = nums.length - 1;
    13. while (left < right) {
    14. int sum = nums[i] + nums[left] + nums[right];
    15. if (sum == 0) {
    16. resList.add(Arrays.asList(nums[i], nums[left], nums[right]));
    17. // 这里面也要变化
    18. left++;
    19. right--;
    20. // 内部也要有重复的验证
    21. while (left < right && nums[left] == nums[left - 1]) left++;
    22. while (left < right && nums[right] == nums[right+ 1]) right--;
    23. } else if (sum < 0) {
    24. left++;
    25. } else {
    26. right--;
    27. }
    28. }
    29. }
    30. return resList;
    31. }
    32. }
    1. class Solution {
    2. public List<List<Integer>> threeSum(int[] nums) {
    3. List<List<Integer>> resList = new ArrayList<>();
    4. // 特殊值判断
    5. if (nums == null || nums.length == 1 || nums.length == 2) {
    6. return resList;
    7. }
    8. // 先对nums进行排序
    9. Arrays.sort(nums);
    10. for (int i = 0; i < nums.length - 2; i++) {
    11. // i最多扩展到倒数第三位
    12. // 因为已经排过序,如果num[i]>0则必然无解。
    13. if (nums[i] > 0) {
    14. return resList;
    15. }
    16. // !!!且如果当前值与下一个值相同,则会存在与之前一样的重复解,跳过这个,上一个解已经记录
    17. // i=0时必然无法与前一个数比较
    18. if (i > 0 && nums[i] == nums[i - 1]) {
    19. continue;
    20. }
    21. // 当前元素记录下来
    22. int cur = nums[i];
    23. // 定义双指针L,R
    24. int L = i + 1, R = nums.length - 1;
    25. while (L < R) {
    26. // 在遍历中寻找有无合适的值
    27. int temp = cur + nums[L] + nums[R];
    28. // 如果temp值大于 0,说明 nums[R] 太大,R 左移。不可能是L右移,temp只会更大。
    29. // 如果temp值小于 0,说明 nums[L] 太大,L 左移。同理。
    30. if (temp == 0) {
    31. // 这里需要讨论几点:去重+移动
    32. // 临时list添加元素,并加入resList中
    33. List<Integer> list = new ArrayList<>();
    34. list.add(cur);
    35. list.add(nums[L]);
    36. list.add(nums[R]);
    37. resList.add(list);
    38. // 去重操作:判断左届或右界是否与相邻为重复,重复就需要跳过
    39. while (L < R && nums[L] == nums[L + 1]) L++;
    40. while (L < R && nums[R] == nums[R - 1]) R--;
    41. // 否则正常向后遍历
    42. L++;
    43. R--;
    44. } else if (temp > 0) {
    45. R--;
    46. } else if (temp < 0) {
    47. L++;
    48. }
    49. }
    50. }
    51. return resList;
    52. }
    53. }