【每日一题Day260】LC15三数之和 | 排序 + 双指针

简介: 【每日一题Day260】LC15三数之和 | 排序 + 双指针

三数之和【LC15】

给你一个整数数组 nums ,判断是否存在三元组[nums[i], nums[j], nums[k]] 满足 i != ji != kj != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

**注意:**答案中不可以包含重复的三元组。

排序+双指针
  • 思路
  • 首先对数组进行排序,然后遍历数组,在确定nums[i]的情况下,在数组nums[i+1,n-1]中使双指针法(前后指针),确定另外两个元素,判断这三个元素之和sumtarget的大小:

image.png

  • 如果nums[i] + nums[left] + nums[right] > 0,说明right下标应该向左移动
    去重:while (left < right && nums[right] == nums[right + 1]) right--;【非必须】
  • 如果nums[i] + nums[left] + nums[right] < 0,说明left下标应该向右移动
    去重: while (left < right && nums[left] == nums[left - 1]) left++;【非必须】

如果nums[i] + nums[left] + nums[right] == 0,说明找到了三元组,双指针同时收缩,right--;left++


去重: while (right > left && nums[right] == nums[right - 1]) right--;

while (right > left && nums[left] == nums[left + 1]) left++;

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);
        for (int i = 0; i < nums.length - 2; i++){
            if (nums[i] > 0){
                return res;
            }
            if (i > 0 && nums[i] == nums[i-1] ){
                continue;
            }
            int left = i + 1;
            int right = nums.length - 1;
            while (left < right){
                int sum = nums[i] + nums[left] + nums[right];
                if (sum > 0){
                    right--;
                    // 非必须
                    while(left < right && nums[right] == nums[right+1]){
                        right--;
                    }
                }else if (sum < 0){
                    // 非必须
                    left++;
                    while (left < right && nums[left-1] == nums[left]){
                        left++;
                    }
                }else{
                    res.add(Arrays.asList(nums[i],nums[left],nums[right]));
                    while(left < right && nums[right] == nums[right-1]){
                        right--;
                    }
                    while (left < right && nums[left+1] == nums[left]){
                        left++;
                    }
                    right--;
                    left++;
                }
            }
        }
        return res;
    }
}
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> res = new ArrayList<>();
        int len = nums.length;
        int i  = 0;
        while (i < len - 2){
            twoSum(nums,i,res);
            int temp = nums[i];
            while (i < len && temp == nums[i]){
                i++;
            }
        }
        return res;
    }
    public void twoSum(int[] numbers, int i, List<List<Integer>> res ) {
        int len = numbers.length;
        int left = i + 1;
        int right = len - 1;
        while(left < right){
            if ( numbers[i] + numbers[left] + numbers[right] == 0){
                res.add(Arrays.asList(numbers[i],numbers[left],numbers[right]));
                int temp = numbers[left];
                while (numbers[left] == temp && left < right){
                    left++;
                }
            }else if(numbers[i] + numbers[left] + numbers[right] > 0){
                right--;
            }else {
                left++;
            }
        }
    }
}

image.png


目录
相关文章
|
7月前
【每日一题Day266】LC18四数之和 | 排序+双指针
【每日一题Day266】LC18四数之和 | 排序+双指针
44 1
|
7月前
【每日一题Day175】LC1147段式回文 | 贪心 +双指针
【每日一题Day175】LC1147段式回文 | 贪心 +双指针
49 0
|
7月前
|
机器学习/深度学习
【每日一题Day196】LC2106摘水果 | 枚举+前缀和数组 同向双指针+二分查找
【每日一题Day196】LC2106摘水果 | 枚举+前缀和数组 同向双指针+二分查找
60 0
|
7月前
【每日一题Day149】LC2389和有限的最长子序列 | 贪心+前缀和+二分查找
【每日一题Day149】LC2389和有限的最长子序列 | 贪心+前缀和+二分查找
48 0
|
7月前
【每日一题Day293】LC23合并K个升序链表 | K指针 堆排序 归并排序
【每日一题Day293】LC23合并K个升序链表 | K指针 堆排序 归并排序
47 0
|
7月前
【每日一题Day331】LC2560打家劫舍 IV | 二分查找 + 贪心
【每日一题Day331】LC2560打家劫舍 IV | 二分查找 + 贪心
47 0
|
7月前
【每日一题Day150】LC1616分割两个字符串得到回文串 | 双指针+贪心
【每日一题Day150】LC1616分割两个字符串得到回文串 | 双指针+贪心
41 0
|
7月前
|
存储
【每日一题Day294】LC88合并两个有序数组 | 双指针
【每日一题Day294】LC88合并两个有序数组 | 双指针
46 0
|
7月前
【每日一题Day306】LC228汇总区间 | 双指针
【每日一题Day306】LC228汇总区间 | 双指针
40 0
|
7月前
【每日一题Day261】LC16最接近的三数之和 | 双指针
【每日一题Day261】LC16最接近的三数之和 | 双指针
41 0