力扣15. 三数之和

该篇博客介绍了如何使用排序和双指针算法解决寻找数组中和为0的不重复三元组的问题。首先对数组进行排序,然后通过三层循环找到满足条件的三数组合,同时避免重复解的出现。在循环过程中,通过调整左右指针来优化搜索过程,提高效率。
摘要由CSDN通过智能技术生成

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

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

 

法1:排序+双指针

本题的难点在于如何去除重复解。

为了保证搜索出来的三元组不重复,先对数组nums进行排序,同时每层循环进行判断,当前遍历到的数不等于本层循环上一个遍历到的数时才进行下一步遍历。

算法流程:

特判,对于数组长度 n,如果数组为 null 或者数组长度小于 3,返回 []。

对数组进行排序。

遍历排序后数组:

   若 nums[i]>0:因为已经排序好,所以后面不可能有三个数加和等于 0,直接返回结果。

   对于重复元素:跳过,避免出现重复解

   令左指针L=i+1,右指针 R=n−1,当 L<R 时,执行循环:

      当 nums[i]+nums[L]+nums[R]==0,将解加入结果列表,判断左界和右界是否和下一位置重复,去除重复解。并同时将 L,R 移到下一位置,寻找新的解

      若和大于 0,说明 nums[R] 太大,R 左移

      若和小于 0,说明 nums[L] 太小,L 右移

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        int n = nums.length;
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        if(n<3) return ans;
        Arrays.sort(nums);
        if(nums[0]>0) return ans;//排序后,最小元素大于0则肯定不存在三数和为0
        for(int i = 0;i<n;i++){
            if(i>0&&nums[i]==nums[i-1])//跳过本层重复元素
                continue;
            int left = i+1,right = n-1;
            while(left<right){
                if(nums[i]+nums[left]+nums[right]==0){
                    List<Integer> list = new ArrayList<Integer>();
                    list.add(nums[i]);
                    list.add(nums[left]);
                    list.add(nums[right]);
                    ans.add(list);
                    while(left<right&&nums[left]==nums[left+1])//跳过本层重复元素
                        left++;
                    while(left<right&&nums[right]==nums[right-1])//跳过本层重复元素
                        right--;
                    left++;
                    right--;
                }
                else if(nums[i]+nums[left]+nums[right]>0)
                    right--;
                else
                    left++;
            }
        }
        return ans;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值