数组操作多数之和

71 阅读2分钟

3数之和


给定n个整数的数组S,S中是否有元素a,b,c 使得a + b + c = 0?在数组中找到所有唯一的三元组 零的总和。


 public static List<List<Integer>> threeSum(int[] nums){
        List<List<Integer>> res=new ArrayList<>();
        if(nums.length<3)return res;
        Arrays.sort(nums);
        final int target=0;
        for (int i = 0; i <nums.length-2 ; ++i) {
            if(i>0 && nums[i]==nums[i-1]) continue;
            int j=i+1;
            int k=nums.length-1;
            while (j<k){
                if(nums[i]+nums[j]+nums[k]<target){
                    ++j;
                    while (nums[j]==nums[j-1] && j<k) ++j;
                }else if(nums[i]+nums[j]+nums[k]>target){
                    --k;
                    while (nums[k]==nums[k+1]&&j<k)--k;
                }else{
                    res.add(Arrays.asList(nums[i],nums[j],nums[k]));
                    ++j;
                    --k;
                    while (nums[j]==nums[j-1]&&j<k)++j;
                    while (nums[k]==nums[k+1]&&j<k)--k;
                }
            }
        }
        return res;
    }

最接近的3数之和


给定n个整数的数组S,在S中找到三个整数,使得 总和最接近给定数字target。返回三者的总和 整数。您可以假设每个输入都只有一个解决方案。 例如,给定数组S = {-1 2 1-4},目标 = 1。 最接近目标的总和为2。(-1 + 2 + 1 = 2)。


 public static int threeSumCloses(int[] nums,int target){
        int res=0;
        int min=Integer.MAX_VALUE;
        Arrays.sort(nums);
        for (int i = 0; i <nums.length-1 ; ++i) {
            int j=i+1;
            int k=nums.length-1;
            while (j<k){
                final int sum=nums[i]+nums[j]+nums[k];
                final int gap=Math.abs(sum-target);
                if(gap<min){
                    res=sum;
                    min=gap;
                }
                if(sum<target)++j;
                else --k;
            }
        }
        return res;
    }

4数之和


给定n个整数的数组S,是否有元素a,b,c和d 在S中,a + b + c + d = 目标?在中查找所有独特的四位数 给出目标总和的数组。 注: 四元组 (a,b,c,d) 中的元素必须按非降序排列。 例如,给定数组S = {1 0 -2 2},目标 = 0。


map缓存

   public static List<List<Integer>> fourSum(int[] nums,int target){
        List<List<Integer>> res=new ArrayList<>();
        if(nums.length<4)return res;
        Arrays.sort(nums);
        for (int i = 0; i <nums.length-3 ; ++i) {
            if(i>0&&nums[i]==nums[i-1])continue;
            for (int j = i+1; j <nums.length-2 ; ++j) {
                if(j>i+1&&nums[j]==nums[j-1])continue;
                int k=j+1;
                int l=nums.length-1;
                while (k<l){
                    final int sum=nums[i]+nums[j]+nums[k]+nums[l];
                    if(sum<target){
                        ++k;
                        while (nums[k]==nums[k-1]&&k<l)++k;
                    }else if(sum>target){
                        --l;
                        while (nums[l]==nums[l+1]&&k<l)--l;
                    }else{
                        res.add(Arrays.asList(nums[i],nums[j],nums[k],nums[l]));
                        ++k;
                        --l;
                        while (nums[k]==nums[k-1]&&k<l)++k;
                        while (nums[l]==nums[l+1]&&k<l)--l;
                    }
                }
            }
        }
        return res;
    }

 public static List<List<Integer>> fourSumTwo(int[] nums,int target){
        List<List<Integer>> res=new ArrayList<>();
        if(nums.length<4)return res;
        Arrays.sort(nums);
        final HashMap<Integer,ArrayList<int[]>> cache=new HashMap<>();
        for (int i = 0; i <nums.length ; ++i) {
            for (int j = i+1; j <nums.length ; ++j) {
                ArrayList<int[]> value=cache.get(nums[i]+nums[j]);
                if(value==null){
                    value=new ArrayList<>();
                    cache.put(nums[i]+nums[j],value);
                }
                value.add(new int[]{i,j});
            }
        }

        final HashSet<String> used=new HashSet<>();
        for (int i = 0; i <nums.length ; ++i) {
            if(i>0&&nums[i]==nums[i-1])continue;
            for (int j = i+1; j <nums.length-2 ; ++j) {
                if(j>i+1&&nums[j]==nums[j-1])continue;
                final ArrayList<int[]> list=cache.get(target-nums[i]-nums[j]);
                if(list==null)continue;
                for (int[] pair:list){
                    if(j>=pair[0])continue;
                    final Integer[] sol=new Integer[]{nums[i],nums[j],nums[pair[0]],nums[pair[1]]};
                    Arrays.sort(sol);
                    final String key=Arrays.toString(sol);
                    if(!used.contains(key)){
                        res.add(Arrays.asList(sol));
                        used.add(key);
                    }
                }
            }
        }
        return res;
    }