标签:
Given n distinct positive integers, integer k (k <= n) and a number target.
Find k numbers where sum is target. Calculate how many solutions there are?
Given [1,2,3,4]
, k = 2
, target = 5
.
There are 2
solutions: [1,4]
and [2,3]
.
Return 2
.
分析:
第一种方法用递归,但是超时了。
1 public class Solution { 2 /** 3 * @param A: an integer array. 4 * @param k: a positive integer (k <= length(A)) 5 * @param target: a integer 6 * @return an integer 7 */ 8 public int kSum(int A[], int k, int target) { 9 // write your code here 10 11 int[] total = new int[1]; 12 helper(A, 0, k, 0, target, 0, total); 13 return total[0]; 14 } 15 16 public void helper(int[] A, int index, int k, int count, int target, int total, int[] kk) { 17 if (count > k || index >= A.length || total > target) return; 18 19 total += A[index]; 20 count++; 21 22 if (count == k && total == target) { 23 kk[0]++; 24 } 25 26 helper(A, index + 1, k, count, target, total, kk); 27 total -= A[index]; 28 count--; 29 helper(A, index + 1, k, count, target, total, kk); 30 } 31 }
很明显,the preferred approach is DP. 但是如何做呢?我做不出来。 :-( 还是直接copy paste其它牛人的解答吧。
if (j == 0 && t == 0) {
// select 0 number from i to the target: 0
D[i][j][t] = 1;
}
1. 状态表达式:
D[i][j][t] = D[i - 1][j][t];
if (t - A[i - 1] >= 0) {
D[i][j][t] += D[i - 1][j - 1][t - A[i - 1]];
}
意思就是:
(1)我们可以把当前A[i - 1]这个值包括进来,所以需要加上D[i - 1][j - 1][t - A[i - 1]](前提是t - A[i - 1]要大于0)
(2)我们可以不选择A[i - 1]这个值,这种情况就是D[i - 1][j][t],也就是说直接在前i-1个值里选择一些值加到target.
1 public class Solution { 2 /** 3 * @param A: an integer array. 4 * @param k: a positive integer (k <= length(A)) 5 * @param target: a integer 6 * @return an integer 7 */ 8 public int kSum(int A[], int k, int target) { 9 10 if (target < 0) { 11 return 0; 12 } 13 14 int len = A.length; 15 16 int[][][] D = new int[len + 1][k + 1][target + 1]; 17 18 for (int i = 0; i <= len; i++) { 19 for (int j = 0; j <= k; j++) { 20 for (int t = 0; t <= target; t++) { 21 if (j == 0 && t == 0) { 22 // select 0 number from i to the target: 0 23 D[i][j][t] = 1; 24 } else if (!(i == 0 || j == 0 || t == 0)) { 25 D[i][j][t] = D[i - 1][j][t]; 26 if (t - A[i - 1] >= 0) { 27 D[i][j][t] += D[i - 1][j - 1][t - A[i - 1]]; 28 } 29 } 30 } 31 } 32 } 33 return D[len][k][target]; 34 } 35 }
Given n unique integers, number k (1<=k<=n) and target.
Find all possible k integers where their sum is target.
Given [1,2,3,4]
, k = 2
, target = 5
. Return:
[ [1,4], [2,3] ]
1 public class Solution { 2 /** 3 * @param A: an integer array. 4 * @param k: a positive integer (k <= length(A)) 5 * @param target: a integer 6 * @return a list of lists of integer 7 */ 8 public ArrayList<ArrayList<Integer>> kSumII(int[] A, int k, int target) { 9 // write your code here 10 ArrayList<ArrayList<Integer>> allList = new ArrayList<ArrayList<Integer>>(); 11 ArrayList<Integer> list = new ArrayList<Integer>(); 12 if (A == null || A.length == 0 || k == 0) return allList; 13 14 helper(allList, list, 0, A, k, 0, target, 0); 15 return allList; 16 } 17 18 public void helper(ArrayList<ArrayList<Integer>> allList, ArrayList<Integer> list, int index, int[] A, int k, int count, int target, int total) { 19 if (count > k || index >= A.length || total > target) return; 20 21 list.add(A[index]); 22 total += A[index]; 23 count++; 24 25 if (count == k && total == target) { 26 allList.add(new ArrayList<Integer>(list)); 27 } 28 29 helper(allList, list, index + 1, A, k, count, target, total); 30 total -= list.get(list.size() - 1); 31 list.remove(list.size() - 1); 32 count--; 33 helper(allList, list, index + 1, A, k, count, target, total); 34 } 35 }
Reference:
http://www.cnblogs.com/yuzhangcmu/p/4279676.html
标签:
原文地址:http://www.cnblogs.com/beiyeqingteng/p/5642185.html