Nsum问题

两数之和

1先排序,再用首尾双指针

2 判断是否包含,若包含则放回,map.containsKey() ,不然就加入hashmap

三数之和(for 找到任一一个元素,再用两数之和)

在Java中,asList 方法通常用于将一个数组转换为一个 List。它是 java.util.Arrays 类中的一个静态方法,使用起来非常简单。

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> res=new ArrayList<>();
        for(int i=0;i<nums.length-2;i++){
            if(nums[i]>0) break;
            if(i>0&&nums[i]==nums[i-1]) continue;//树层去重
            int target=-nums[i];
            int p1=i+1,p2=nums.length-1;
            while(p1<p2){
                int sum=nums[p1]+nums[p2];//一直在变
                if(sum>target){
                    p2--;
                }else if(sum<target){
                    p1++;
                }else{
                   res.add(Arrays.asList(nums[i], nums[p1], nums[p2]));
                   while(p1<p2&&nums[p1]==nums[p1+1]) p1++;
                   while(p1<p2&&nums[p2]==nums[p2-1]) p2--;//树枝去重
                   p1++;
                   p2--;
                }
            }
        }
        return res;
}
}

四数之和

For枚举第一个数,for 枚举第二个数,接下来就是两数之和,考虑去重

long x long y是担心求和大于int

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        Arrays.sort(nums);
        List<List<Integer>> res=new ArrayList<>();
        int len=nums.length;
        for(int i=0;i<len-3;i++){//找第一个数
            long x=nums[i];
            if(i>0&&nums[i]==nums[i-1]) continue;
            if(x+nums[i+1]+nums[i+2]+nums[i+3]>target) break;//优化1,后面都大于
            if(x+nums[len-1]+nums[len-2]+nums[len-3]<target) continue;//优化2,最大的可能小于跳过
            for(int j=i+1;j<len-2;j++){//找第二个数     
                long y=nums[j];
                if(j>i+1&&nums[j]==nums[j-1]) continue;
                if(x+y+nums[j+1]+nums[j+2]>target) break;
                if(x+y+nums[len-1]+nums[len-2]<target) continue;
                int p1=j+1,p2=len-1;
                while(p1<p2){
                    long target1=target-x-y;
                    if(nums[p1]+nums[p2]>target1){
                        p2--;
                    }else if(nums[p1]+nums[p2]<target1){
                        p1++;
                    }else{
                        res.add(Arrays.asList((int)x,(int)y,nums[p1],nums[p2]));
                        while(p1<p2&&nums[p1]==nums[p1+1]) p1++;
                        while(p1<p2&&nums[p2]==nums[p2-1]) p2--;
                        p1++;
                        p2--;
                    }
                } 
            }
        }
        return res;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值