力扣15.三数之和(java)

力扣15.三数之和


LeetCode笔记汇总

题目

给你一个包含 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
-10^5 <= nums[i] <= 10^5

思路

先考虑特殊情况:nums为空或长度小于三,此时直接返回空的list即可
本题若采用暴力列举法,时间复杂度至少为N^3,况且之后还需要通过hash表来去重,因此排除。
若先将nums排序,则这道问题就会变得简单很多:已知一个有序数组,求其中任意三项和为定值的情况。
再将问题进一步细分:从左边开始定义一个指针i,求出目标值与nums[i]的差值sum=0-nums[i],在数组剩余的部分中,找两个和为sum的项。其中需要处理好left和right指针的增减,并注意避免空指针异常。

当一轮遍历结束后,指针i向左移动一位,此时需要判断两个条件:1.nums[i]的值是否大于0,因为已经排过序,若nums[i]>0则必定没有结果(剪枝)。2.nums[i]的值与nums[i-1]的值是否相同,若相同则属于重复,需去除

代码

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

        if(nums.length < 3 || nums ==null) return ans;

        int left,right,sum;
        Arrays.sort(nums);

        for(int i = 0;i < nums.length;i++){
            if(nums[i] > 0) break;
            //从第二轮开始判断,避免空指针异常
            if(i > 0 && nums[i] == nums[i-1]) continue;
            left = i + 1;
            right = nums.length - 1;
            sum = -nums[i];
            while(left < right){
                if(nums[left] + nums[right] == sum ){
                    ans.add(Arrays.asList(nums[i],nums[left],nums[right]));
                    while (left < right && nums[left] == nums[left+1]) left++;
                    while (left < right && nums[right] == nums[right-1]) right--;
                    left++;
                    right--;
                }else if(nums[left] + nums[right] < sum) 
                    left++;
                else 
                    right--;
            }
        }
        return ans;
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值