三数之和----四数之和----k数之和

本文介绍了一种解决三数之和与四数之和问题的有效算法。通过先对数组进行排序,然后使用双指针技术遍历并寻找符合条件的数字组合。该方法能够避免重复解,并在复杂度上保持高效。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对数组排序后,采取三个指针逼近的方式:
指针i遍历,指针l指针r分别为左右指针,进行比较

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> list=new ArrayList<>();
        Arrays.sort(nums);
        int m=0;
        int l,r;
        for(int i=0;i<nums.length-2;i++){
            if(i==0 || nums[i]>nums[i-1]){
                l=i+1;
                r=nums.length-1;
                while(l<r){
                    if(nums[i]+nums[l]+nums[r]==0){
                        list.add(new ArrayList<Integer>());
                        list.get(m).add(nums[i]);
                        list.get(m).add(nums[l]);
                        list.get(m).add(nums[r]);
                        m++;
                        l++;
                        r--;
                        while(l<r && nums[l]==nums[l-1]){
                            l++;
                        }
                        while(l<r && nums[r]==nums[r+1]){
                            r--;
                        }
                    }else if(nums[i]+nums[l]+nums[r]>0){
                        r--;
                    }else{
                        l++;
                    }
                }
            }
        } 
        return list;
    }
}

四数之和

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> list=new ArrayList<>();
        Arrays.sort(nums);
        int m=0;
        int l,r;
        for(int i=0;i<nums.length-3;i++){
            if(i==0||nums[i]>nums[i-1]){
                for(int j=i+1;j<nums.length-2;j++){
                    if(j==i+1||nums[j]>nums[j-1]){
                        l=j+1;
                        r=nums.length-1;
                        while(l<r){
                            if(nums[i]+nums[j]+nums[l]+nums[r]==target){
                                list.add(new ArrayList<Integer>());
                                list.get(m).add(nums[i]);
                                list.get(m).add(nums[j]);
                                list.get(m).add(nums[l]);
                                list.get(m).add(nums[r]);
                                m++;
                                l++;
                                r--;
                                while(l<r&&nums[l]==nums[l-1]){
                                    l++;
                                }
                                while(l<r&&nums[r]==nums[r+1]){
                                    r--;
                                }
                            }else if(nums[i]+nums[j]+nums[l]+nums[r]>target){
                                r--;
                            }else{
                                l++;
                            }
                        }
                    }
                }
            }
        }
        return list;
    }
}

k数之和

public static ArrayList<List<Integer>> kSum(int nums[],int target,int k, int start){
        ArrayList<List<Integer>> res = new ArrayList<List<Integer>>();
        if(start>=nums.length)
            return res;
        if(k==2){
            int l = start, h = nums.length-1;
            while(l<h){
                if(nums[l]+nums[h]==target){
                    List<Integer> list = new ArrayList<>();
                    list.add(nums[l]);
                    list.add(nums[h]);
                    res.add(list);
                    while(l<h&&nums[l]==nums[l+1])
                        l++;
                    while(l<h&&nums[h]==nums[h-1])
                        h--;
                    l++;
                    h--;
                }else if(nums[l]+nums[h]<target)
                    l++;
                else
                    h--;
            }
            return res;
        }
        if(k>2){
            for(int i=start;i<nums.length-k+1;i++){
                ArrayList<List<Integer>> temp = kSum(nums, target - nums[i], k - 1, i + 1);
                if(temp!=null) {
                    for (List<Integer> l : temp) {
                        l.add(0, nums[i]);
                    }
                    res.addAll(temp);
                }
                while(i<nums.length-1&&nums[i]==nums[i+1]){
                    i++;
                }
            }
            return res;
        }
        return res;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值