leetcode--三数之和为0

在这里插入图片描述

思路:

  • 先排序 ;Arrays.sort() 默认升序排序
  • 双指针
    • left不能放在for循环外,必须要在for循环内,与i相关联,为left = i+1;如果放置在for循环之外,left会出现当left = i 的情况,如例子[-4,-1,0,1,2],当left = i = 1时,right = 4,则 nums[i]+nums[left]+nums[right]=0,那么结果为[-1,-1,2],但是条件数组中-1只有一个。
    • 例如当i=0时,whlie(left<right)会将内部在遍历一次,寻找符合条件的组合。

时间复杂度:外层循环+while 相当于两层for循环 O(N*N)
空间复杂度:额外的排序的空间复杂度为 O(logN)

import java.util.*;

class Code15{
    public static void main(String[] args) {
        int[] nums = {-1,0,1,2,-4};
        List<List<Integer>> result = threeSum(nums);
        System.out.println(result);
    }

    public static List<List<Integer>> threeSum(int[] nums) {
        // 先排序 后双指针
        Arrays.sort(nums);
        List<List<Integer>> res = new ArrayList();

        int len = nums.length;

        for (int i = 0;i < len  ;i++ ) {
            int left = i+1; // left指针要与i关联,不然会出现同一个数被用2次,即i与left相同时
            int right = len - 1;
            if(nums[i]>0){//此数大于0,说明后面的和不可能为0
                break;
            }
            if (i>0 && nums[i] == nums[i - 1]) continue; // 不做处理,执行下面,避免重复
            while (left < right) { // 会将i=0,1,2,...时,与每一个left right组合
                int sum = nums[left] + nums[i] + nums[right];
                if (sum == 0) {
                    res.add(Arrays.asList(nums[left], nums[i], nums[right]));
                    // 当sum=0时候,移动指针,但是该组合已经添加到结果集中,
                    // 如果left指针对应不同索引的值相同,不必再添加,所以索引++,继续找下面的组合
                    if (nums[left] == nums[left + 1]) left++; //避免重复
                    if (nums[right] == nums[right - 1]) right--;//避免重复
                    // 当sum=0满足时,将指针移动寻找其他组合
                    right--;
                    left++;
                } else if (sum > 0) { // 如果sum数大于0,说明要向左移,寻找负数
                    right--;
                } else if (sum < 0) {// 如果sum数小于0,说明要向右移,寻找正数
                    left++;
                }
            }

        }

        return res;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值