hot15-三数之和

在这里插入图片描述
在这里插入图片描述
约束范围:在这里插入图片描述

解法:先排序再降维处理,将三数之和降成一个常数+两数之和。由约束条件知无需处理数组没有三个元素及null的情况。关键是去掉重复的数组。
1、将数组从小到大排序
Arrays.sort(nums);
2、降维处理
a、当常数>0时跳出循环,因为数组是从小到大排序,所以如果第一个数(也就是常数>0,后面的三数之和一定大于0,不符合题意要跳出循环)。
b、常数去重,使用 if(i>0 && nums[i]==nums[i-1]){continue;} 其中i>0是因为考虑到全为0的特殊数组。写成nums[i]==nums[i-1] 而不nums[i]==nums[i+1] 是因为写成nums[i]==nums[i+1] 就会使nums[i]和nums[i+1]这两个常数都无法继续处理,而且会导致缺少解,例如-4,-1,-1,0,1,2。它的解为[-1,-1,2]和[-1,0,-1],写成nums[i]==nums[i+1] continue 会从下标为2的数开始,会漏掉[-1,-1,2]这组解
c、假设nums[i]为常数,有两个指针:left和right,分别指向i的后一位和末尾,而不是指向0和末尾,这样做是为了去重。
d、left和right指针内容去重
while(right >0 && nums[right-1]==nums[right]) {right–;}
while(left<n-1 && nums[left]==nums[left+1]){ left++;}
完整代码:

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
     int n=nums.length;
            Arrays.sort(nums);
            List<List<Integer>> list= new ArrayList<>();
            for(int i=0;i<n;i++){
                int left=i+1;int right=n-1;
                if(nums[i]>0){break;}
                if(i>0 && nums[i]==nums[i-1]){continue;}//考虑到全是0的数组因此i>0 且nums[i]==nums[i-1]
                    while(left<right){
                        int sum=nums[left]+nums[right]+nums[i];
                        if(sum>0){
                            right--;
                        }else if(sum==0){
                            List<Integer> listemp= new ArrayList<>();
                            listemp.add(nums[left]);
                            listemp.add(nums[i]);
                            listemp.add(nums[right]);
                            list.add(listemp);
                            while(right >0 && nums[right-1]==nums[right]) {right--;}
                            while(left<n-1 && nums[left]==nums[left+1]){ left++;}
                            left++;//这里同时使left和right变化是因为剩下为遍历的数组两端与它们各自的前一位,后一位都不同,只移动左或右都无法使三数的和为零,因此要同时向中间逼近。
                            right--;
                        }else{
                            left++;
                        }
                    }
            }
            return list;
    }
}

今日感悟:我先是看完解题再做hot15 三数之和,由于只是按自己理解去重因此花了4天时间求解还没求出来,最后看了答案代码后才解出,最终的代码也和答案差不多。
二刷感悟:今日花了55分钟完成了此题,有许多欠缺考虑的地方。例如常数去重,该用if(i>0 && nums[i]==nums[i-1]){continue;} 而我用while(nums[i+1]==nums[i]){
i++;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值