找出數組中的所有數字之和等於目標值的數組. (可登入LeetCode網站查詢 40. 組合總和 II)
[2,5,2,1,2], 5,
1.排序 [2,5,2,1,2] -> 1,2(1),2(2),2(3),5
2. 1,2(1),2(2) = 5
以2(2)爲起點走下面循環: 1,2(1),2(2),2(3); 1,2(1),2(2),2(3),5 ; 1,2(1),2(2),2(3) ;1,2(1),2(2),5 此三種組合都一定都大於5 所以直接返回.
以2(3)爲起點走下面循環: 因爲1,1,2(1),2(2)循環完要走 1,1,2(1),2(3) 因爲2(3)走的循環一定在以2(2)爲起點的循環中.
public class Solution {
List<List<Integer>> lists = new ArrayList<>();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
// 排序 更好的計算 {4, 1, 1, 4, 4, 2, 3, 5} -> {1, 1, 2, 3, 4, 4, 4, 5} target = 9
// 好處1.起始位置相同無需重新再循環 當下標爲 0 ,值爲1的,我們所得數組,和下標爲1,值1的結果一樣
// 好處2.當等於大於目標值的時候,可以結束此次循環. 1,1,3,4, 等於 9 無需去看 1,1,3,5一定大於9
Arrays.sort(candidates);
ArrayList<Integer> objects1 = new ArrayList<>();
getList(objects1, candidates, 0, target);
return lists;
}
private void getList(ArrayList<Integer> list, int[] ints, Integer x, Integer y) {
for (int i = x; i < ints.length; i++) {
// i > x 說明該層循環已經遍歷1次,所以重複數據無需遍歷 同好處1
// ->循環當前位置 1,1,2,3,4 > 9 結束
// 下次循環 1,1,2,4(此4 下標爲4)
// 不會是 1,1,2,2,4(此4 下標爲5)
if (i > x && ints[i] == ints[i-1] ){
continue;
}
ArrayList<Integer> clone = (ArrayList<Integer>) list.clone();
if (ints[i] == y) {
clone.add(ints[i]);
lists.add(clone);
// 此如見好處2
// ->循環當前位置 2,3,4 = 9 結束
// 下次循環 2,4,5
// 不會是 2,3,5
return;
} else if (ints[i] < y) {
clone.add(ints[i]);
getList(clone, ints, i + 1, y - ints[i]);
} else {
// 此如見好處2 1, 1, 2, 3, 4, 4, 4, 5
// ->循環當前位置 1,1,2,3,4 > 9 結束
// 下次循環 1,1,2,4
// 不會是 1,1,2,3,5
return;
}
}
}
public static void main(String[] args) {
Solution solution = new Solution();
int[] ints = {4, 1, 1, 4, 4, 2, 3, 5}; //1,2
List<List<Integer>> lists = solution.combinationSum2(ints, 9);
lists.forEach(list -> {
System.out.println("================================");
list.forEach(lst -> {
System.out.print(lst + ",");
});
});
}
}