K-SUM

来源:互联网 发布:linux 查看raid卡型号 编辑:程序博客网 时间:2024/04/30 03:59
K-SUM

一个典型的k个数的和相等的问题,所耗时间的N^(k-1),N为给出的数组中元素个数

1、2-sum

给出一个整形数组,从中找出两个元素的值的和等于给定的数
要求:定义的函数twoSum应该返回两个明确的元素,他们的和等于给出的值,并且元素1的下标小于元素2的下标

如:
输入: numbers={2, 7, 11, 15}, target=9
输出: index1=0, index2=1


提示:解决这个方法应该用一个HashMap来实现,每一个数组里的元素,他们的下标索引存储在这个HashMap中

public int[] twoSum(int[] nums, int target) {    if(nums==null || nums.length<2)        return new int[]{0,0};     HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();    for(int i=0; i<nums.length; i++){        if(map.containsKey(nums[i])){            return new int[]{map.get(nums[i]), i};        }else{            map.put(target-nums[i], i);        }    }     return new int[]{0,0};}

时间复杂度是 O(n).

2、4-sum

给定一个有n个元素的数组,找出所有的4个元素使得他们的和等于给定的数
要求:给出的4个元素必须以非递减的形式呈现(如 a ≤ b ≤ c ≤ d),同时给出的解中的4个元素不能完全一样

如, S = {1 0 -1 0 -2 2}, target = 0.

解集是:
(-1,  0, 0, 1)
(-2, -1, 1, 2)
(-2,  0, 0, 2)

public List<List<Integer>> fourSum(int[] nums, int target) {    List<List<Integer>> result = new ArrayList<List<Integer>>();     if(nums==null|| nums.length<4)        return result;     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){                if(nums[i]+nums[j]+nums[k]+nums[l]<target){                    k++;                }else if(nums[i]+nums[j]+nums[k]+nums[l]>target){                    l--;                }else{                    List<Integer> t = new ArrayList<Integer>();                    t.add(nums[i]);                    t.add(nums[j]);                    t.add(nums[k]);                    t.add(nums[l]);                    result.add(t);                    k++;                    l--;                     while(k<l &&nums[l]==nums[l+1] ){                        l--;                    }                     while(k<l &&nums[k]==nums[k-1]){                        k++;                    }                }              }        }    }     return result;}


3、3-sum

给定一个有n个元素的数组,找出3个元素使得他们的和最接近于给定的目标数。返回这3个数的和。

如, S = {-1 2 1 -4}, and target = 1. 
最接近这个目标数的值为 2. (-1 + 2 + 1 = 2).

分析:这个问题类似于2-sum,所以可以用类似的方法解决,如从头和尾用两个指针

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


1 0
原创粉丝点击