題目地址:
https://www.lintcode.com/problem/k-sum-ii/description
給定一個長度爲的正整數數組,數組內數字彼此不同,再給定兩個數和,要求在數組中找所有的個數的組合其和爲。
思路是DFS。爲了剪枝方便,可以先排個序。剪枝的技巧在於:
1、如果枚舉時發現剩下來要枚舉的數不足以填滿個數了,就直接退出本層枚舉(因爲接下來的數就算全加進去,也不夠個),回到遞歸上一層;
2、如果發現某次已經枚舉的數已經到達了個,但和仍然不爲,也可以直接退出本層枚舉(因爲繼續枚舉會得到size大於的組合),回到遞歸上一層;
3、如果發現枚舉到一個大於的數,也可以退出本層枚舉,回到遞歸上一層(因爲接下來枚舉會得到更大的和,不會得到合法的解,所以可以直接退出)。
代碼如下:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Solution {
/*
* @param A: an integer array
* @param k: a postive integer <= length(A)
* @param target: an integer
* @return: A list of lists of integer
*/
public List<List<Integer>> kSumII(int[] A, int k, int target) {
// write your code here
List<List<Integer>> res = new ArrayList<>();
if (A == null || A.length == 0) {
return res;
}
Arrays.sort(A);
dfs(A, k, target, 0, new ArrayList<>(), res);
return res;
}
private void dfs(int[] A, int k, int target, int pos, List<Integer> cur, List<List<Integer>> res) {
if (target == 0 && cur.size() == k) {
res.add(new ArrayList<>(cur));
return;
}
// 這裏是考慮的剪枝情況2
if (cur.size() == k) {
return;
}
// 這裏k - cur.size() <= A.length - i考慮的是剪枝情況1
for (int i = pos; k - cur.size() <= A.length - i; i++) {
if (target >= A[i]) {
cur.add(A[i]);
dfs(A, k, target - A[i], i + 1, cur, res);
cur.remove(cur.size() - 1);
} else {
// 這裏是考慮的剪枝情況3
return;
}
}
}
}
時間複雜度,空間複雜度。