15.三数之和(LeetCode)java

个人理解:

1.使用双指针做法,首先对数组进行排序

        第一重for循环控制第一个数,对数组进行遍历。双指针初始化为left=i+1, rigth=nums.length-1。然后使用while循环移动双指针寻找合适的数。因为返回的是数,不是下标,数不能重复,所以需要去重。对于第一重for循环,当i大于0的时候,要判断是否和前一个数相同,如果相同,则跳过当前数进行去重。

2.双指针移动

当nums[i]+nums[left]+nums[right]>0时,说明大了,最右边的right指针需要减减操作(right--)

当nums[i]+nums[left]+nums[right]<0时,说明小了,最左边的left指针需要加加操作(left++)

当nums[i]+nums[left]+nums[right]==0时,开始收集结果。

3.结果收集

收集完结果后,要移动双指针,这时候也要对双指针进行去重。

指针去重操作:

        对于left指针,如果nums[left]==nums[left+1],说明下一位重复,那么left要持续++;

        对于right指针,如果nums[right]==nums[right-1],说明下一位重复,那么right要持续--;

以上两种情况都要主要前提条件,即left<right

无论以上两种情况是否执行,都需要left++和right--更新双指针。

最后将结果收集 res.add(Arrays.asList(nums[i],nums[left],nums[right]))

res是List<List<Integer>>类型,Arrays.asList()是将一组元素变为List

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;i++){
            if(nums[i]>0)   //如果第一个元素大于0,直接跳出循环
                break ;
            if(i>0&&nums[i]==nums[i-1])  //对于第一个元素,去重
                continue;
            int left=i+1;   // 双指针
            int right=nums.length-1;
            // 指针开始移动
            while(left<right){
                if(nums[i]+nums[left]+nums[right]>0){  // 太大了,右指针移动
                    right--;
                }
                else if(nums[i]+nums[left]+nums[right]<0){  // 太小了,左指针移动
                    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]==nums[left+1])
                        left++;
                    // 移动双指针
                    left++;
                    right--;
                }
            }
        }
        return res; 
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值