leetcode刷题 15. 三数之和(Java)Medium 排序+双指针

398 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1.题目描述

给你一个包含 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

2.解法:排序 + 双指针

这道题和Leetcode 1.两数之和一个概念,该题相当于两数之和的进阶版。 但两数之和因为只有两个数,所以可以通过哈希表来减少一层循环。但本题是三个数,所以哈希表不好用。

2.1 思路

这道题的难点在需要排除重复的数,就不能用枚举法,而且判定的时候麻烦了许多。

  • 首先为了便于排除重复的数,就先将数组排序。

因为排序之后顺序是从小到大的,所以最左边的就是最小的,最右边的就是最大的。

  • 排除最小的值nums[left]都大于0的情况。

  • 之后将重复的nums[left]值去掉。

  • 最后while进行双指针的判断,如果三数之和为0放进答案,为了防止有重复的答案,所以重复的nums[left]和nums[right]的值就跳过;如果三数之和大于0,则说明right太大了;如果三数之和小于0,则说明left太小了。分别移动。

最后遍历结束就可以返回答案了。

2.2 Java代码

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> ans = new ArrayList<>();
        int len = nums.length;
        Arrays.sort(nums);

        for(int left = 0;left <len;left++){
            if(nums[left]>0){
                return ans;
            }
            if(left>0 && nums[left] == nums[left-1]){
                continue;
            }
            int mid = left+1,right = len-1;
            while(mid<right){
                if(nums[left]+nums[mid]+nums[right] == 0){
                    List<Integer> temp = new ArrayList<>();
                    temp.add(nums[left]);
                    temp.add(nums[mid]);
                    temp.add(nums[right]);
                    ans.add(temp);
                    while(mid<right&&nums[mid]==nums[mid+1]){
                        mid++;
                    }
                    while(mid<right&&nums[right]==nums[right-1]){
                        right--;
                    }
                    mid++;
                    right--;
                }
                else if(nums[left]+nums[mid]+nums[right] < 0){
                    mid++;
                }
                else{
                    right--;
                }
            }
        }
        return ans;
    }
}