回溯算法之-組合總和請看:https://www.jianshu.com/p/2a9856b96a86
leetcode 46 全排列
給定一個 沒有重複數字的序列,返回其所有可能的全排列。
先來說下排列和組合的區別,排列是給定可選擇數組中每個數字都需要被使用;而組合則是根據題目要求可選擇數組中數字的任意組合,並不是每個數字都需要,也並不是每個數字都需要使用。
還是套用https://www.jianshu.com/p/2a9856b96a86
一文中的回溯算法模板
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
// 排序非必須
Arrays.sort(nums);
// 判斷數組中元素是否被使用,這裏也可以使用HashSet來判斷(因爲題幹中提示無重複數字)
int[] used = new int[nums.length];
help(res, nums, new ArrayList<Integer>(), used);
return res;
}
private void help(List<List<Integer>> res, int[] nums, ArrayList<Integer> list, int[] used) {
// 當集合元素=數組元素個數時,即代表這是一個全排列
if (list.size() == nums.length) {
res.add(new ArrayList<>(list));
return;
}
for (int i = 0; i < nums.length; i++) {
// 如果該元素已經被使用過了,跳過該元素
if (used[i] == 1) {
continue;
}
// 標識該元素已經被使用
used[i] = 1;
list.add(nums[I]);
help(res, nums, list, used);
// 回溯過後將該元素置爲未使用
used[i] = 0;
list.remove(list.size()-1);
}
}
Leetcode 47 全排列2
與46題相比,區別在於給定數字包含重複元素
套模板
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
// 排序非必須
Arrays.sort(nums);
// 判斷數組中元素是否被使用,這裏也可以使用HashSet來判斷(因爲題幹中提示無重複數字)
int[] used = new int[nums.length];
help(res, nums, new ArrayList<Integer>(), used);
return res;
}
private void help(List<List<Integer>> res, int[] nums, ArrayList<Integer> list, int[] used) {
// 當集合元素=數組元素個數時,即代表這是一個全排列
if (list.size() == nums.length) {
res.add(new ArrayList<>(list));
return;
}
for (int i = 0; i < nums.length; i++) {
// 如果該元素已經被使用過了,跳過該元素
if (used[i] == 1) {
continue;
}
// 這裏是與上一題唯一不同的地方,需要進行去重,如果當前數字和前一個數字相等,並且前一個數字是已經回溯過的,則代表他們是樹結構的同一層,則進行跳過
if(i>0 && nums[i] == nums[i-1] && (used[i-1]==0)){
continue;
}
// 標識該元素已經被使用
used[i] = 1;
list.add(nums[I]);
help(res, nums, list, used);
// 回溯過後將該元素置爲未使用
used[i] = 0;
list.remove(list.size()-1);
}
}