题目描述

原题链接

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。

示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]

示例 2:
输入:nums = []
输出:[]

示例 3:
输入:nums = [0]
输出:[]

提示:

  • 0 <= nums.length <= 3000
  • -105 <= nums[i] <= 105

个人解法

JavaScript

  1. /*
  2. * @lc app=leetcode.cn id=15 lang=javascript
  3. *
  4. * [15] 三数之和
  5. */
  6. // @lc code=start
  7. /**
  8. * @param {number[]} nums
  9. * @return {number[][]}
  10. */
  11. var threeSum = function (nums) {
  12. const result = [];
  13. const resultMap = new Map();
  14. let left = 0;
  15. let right = nums.length - 1;
  16. if (nums.length < 3) {
  17. return [];
  18. }
  19. const arr = nums.sort((a, b) => a - b);
  20. for (; arr[left] < 0; left++) {
  21. right = nums.length - 1;
  22. let mid = left + 1;
  23. while (mid < right) {
  24. const temp = arr[left] + arr[mid] + arr[right];
  25. if (temp === 0) {
  26. const str = `${arr[left]}${arr[mid]}${arr[right]}`;
  27. if (!resultMap.has(str)) {
  28. resultMap.set(str);
  29. result.push([arr[left], arr[mid], arr[right]]);
  30. }
  31. while (mid < right && nums[mid] == nums[mid + 1]) mid++; // 去重
  32. while (mid < right && nums[right] == nums[right - 1]) right--; // 去重
  33. mid++;
  34. right--;
  35. } else if (temp > 0) {
  36. right--;
  37. } else if (temp < 0) {
  38. mid++;
  39. }
  40. }
  41. }
  42. while (arr[left] < 0 && left < right) {
  43. left++;
  44. }
  45. while (arr[right] > 0 && left < right) {
  46. right--;
  47. }
  48. if (right - left >= 2) {
  49. result.push([0, 0, 0])
  50. }
  51. return result;
  52. };
  53. // @lc code=end

Java

  1. class Solution {
  2. public static List<List<Integer>> threeSum(int[] nums) {
  3. List<List<Integer>> listList = new ArrayList<>();
  4. int i, left, right;
  5. int l = nums.length;
  6. if(l < 3) {
  7. return listList;
  8. }
  9. Arrays.sort(nums);
  10. for (i = 0; i < l; i++) {
  11. if (nums[i] > 0) {
  12. return listList;
  13. }
  14. if (i>0&&nums[i] == nums[i - 1]) {
  15. continue;
  16. }
  17. left = i + 1;
  18. right = l - 1;
  19. while (left < right) {
  20. if (nums[i] + nums[left] + nums[right] < 0) {
  21. left=left+1;
  22. } else if (nums[i] + nums[left] + nums[right] > 0) {
  23. right=right-1;
  24. } else if (nums[i] + nums[left] + nums[right] == 0) {
  25. List<Integer> list = new ArrayList<>();
  26. list.add(nums[i]);
  27. list.add(nums[left]);
  28. list.add(nums[right]);
  29. listList.add(list);
  30. while (left<right&&nums[left] == nums[left + 1]) {
  31. left=left+1;
  32. }
  33. while (left<right && nums[right] == nums[right - 1]) {
  34. right=right-1;
  35. }
  36. left=left+1;
  37. right=right-1;
  38. }
  39. }
  40. }
  41. return listList;
  42. }
  43. }

更优解法

Java

JavaScript

  1. /**
  2. * @param {number[]} nums
  3. * @return {number[][]}
  4. */
  5. var threeSum = function(nums) {
  6. let ans = [];
  7. const len = nums.length;
  8. if(nums == null || len < 3) return ans;
  9. nums.sort((a, b) => a - b); // 排序
  10. for (let i = 0; i < len ; i++) {
  11. if(nums[i] > 0) break; // 如果当前数字大于0,则三数之和一定大于0,所以结束循环
  12. if(i > 0 && nums[i] == nums[i-1]) continue; // 去重
  13. let L = i+1;
  14. let R = len-1;
  15. while(L < R){
  16. const sum = nums[i] + nums[L] + nums[R];
  17. if(sum == 0){
  18. ans.push([nums[i],nums[L],nums[R]]);
  19. while (L<R && nums[L] == nums[L+1]) L++; // 去重
  20. while (L<R && nums[R] == nums[R-1]) R--; // 去重
  21. L++;
  22. R--;
  23. }
  24. else if (sum < 0) L++;
  25. else if (sum > 0) R--;
  26. }
  27. }
  28. return ans;
  29. };