给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素,a、b、c;使得 a+b+c = 0;找出所有和为 0 且不重复的三元组;比如:nums = [-1,0,1,2,-1,-4];输出:[[-1,-1,2],[-1,0,1]]
- 流程:
-
特殊判断,数组为 null 或 数组长度小于 3,返回[];在遍历数组的时候,如果当前下标的值与前一个下标对应的值相等,也不计算了,因为上一个数已经做过运算了
-
数组排序
-
遍历排序后的数组:{-4,-1,-1,0,1,2}
-
若 nums[i]>0;因为已经排序好,所以后面不可能有三个数相加等于 0 的情况了;直接返回结果
-
对于重复元素:跳过,避免出现重复解
-
定义三个指针,一个是遍历 nums 的 i、一个是左指针 L=i+1、一个是 R=n-1、
-
Q.为什么左指针 L=i+1,而不是从 0 开始呢;
-
A.比如我们现在遍历到 i=3,值为 0;这时候左指针的值为 1,但是为什么不是 -4 呢,因为当初在遍历到 -4 的时候,已经和 0 计算过了,所以左指针 L=i+1
- 如果三个指针的值相加的结果 < 0,这个时候要左指针右移
-
Q.为什么左指针右移?
-
A.现在相加结果 < 0,左右指针都要增加,但是右指针已经最大值了,没法右移了,于是左指针右移动
- 如果三个指针的值相加结果 > 0,这个时候右指针左移
-
Q.为什么右指针左移?
-
A.现在相加结果 > 0,左右指针都要减少,但是左指针减少的相 加过程咱们已经走过了,于是右指针左移
-
public List<List<Integer>> threeSum(int[] nums) { List<List<Integer>> lists = new ArrayList<>(); Arrays.sort(nums);//排序{-4,-1,-1,0,1,2} int len = nums.length; for (int i = 0; i < len; ++i) { if (nums[i] > 0) { break; } if (i > 0 && nums[i] == nums[i - 1]) { continue; } int curr = nums[i]; int L = i + 1, R = len - 1; while (L < R) { int tmp = curr + nums[L] + nums[R]; if (tmp == 0) { List<Integer> list = new ArrayList<>(); list.add(curr); list.add(nums[L]); list.add(nums[R]); lists.add(list); ++L; --R; } else if (tmp < 0) { ++L; } else { --R; } } } //用于处理去重 List<List<Integer>> result = new ArrayList<>(); HashMap<String, String> hashMap = new HashMap<>(); for (List<Integer> integers : lists) { String key = integers.toString(); if (!hashMap.containsKey(key)) { hashMap.put(key, "1"); result.add(integers); } } return result; }