方法:
1. 递归函数
2. 栈3. 队列
4. 深度优先搜索( DFS , Depth-First Search),又常称为回溯法
5. 广度优先搜索(BFS, Breadth-First Search)
1. Subsets:DFS
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
List<Integer> list = new ArrayList<Integer>();
if (nums == null || nums.length == 0) {
return result;
}
Arrays.sort(nums);
dfs(nums, 0, list, result);
return result;
}
private void dfs(int[] nums, int pos, List<Integer> list,List<List<Integer>> ret) {
// add temp result first
ret.add(new ArrayList<Integer>(list));
for (int i = pos; i < nums.length; i++) {
list.add(nums[i]);
dfs(nums, i + 1, list, ret);
list.remove(list.size() - 1);
}
}
有重复元素的子集
public ArrayList<ArrayList<Integer>> subsetsWithDup(ArrayList<Integer> S) {
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
if (S == null) return result;
//
Collections.sort(S);
List<Integer> list = new ArrayList<Integer>();
dfs(S, 0, list, result);
return result;
}
private void dfs(ArrayList<Integer> S, int pos, List<Integer> list, ArrayList<ArrayList<Integer>> result) {
result.add(new ArrayList<Integer>(list));
for (int i = pos; i < S.size(); i++) {
// exlude duplicate
if (i != pos && S.get(i) == S.get(i - 1)) {
continue;
}
list.add(S.get(i));
dfs(S, i + 1, list, result);
list.remove(list.size() - 1);
}
}
2. Permutations
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
if (nums == null || nums.length == 0) return result;
List<Integer> list = new ArrayList<Integer>();
dfs(nums, list, result);
return result;
}
private void dfs(int[] nums, List<Integer> list, List<List<Integer>>result) {
if (list.size() == nums.length) {
result.add(new ArrayList<Integer>(list));
return;
}
for (int i = 0; i < nums.length; i++) {
if (list.contains(nums[i])) continue;
list.add(nums[i]);
dfs(nums, list, result);
list.remove(list.size() - 1);
}
}
含有重复元素的排列:
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
if (nums == null || nums.length == 0) {
return result;
}
Arrays.sort(nums);
while (true) {
// step1: add list to result
List<Integer> list = new ArrayList<Integer>();
for (int i : nums) {
list.add(i);
}
result.add(list);
// step2: find nums[k] < nums[k + 1] backward
int k = -1;
for (int i = nums.length - 2; i >= 0; i--) {
if (nums[i] < nums[i + 1]) {
k = i;
break;
}
}
if (k == -1) break;
// step3: swap with nums[l]
int l = nums.length - 1;
while (l > k && nums[l] <= nums[k]) {
l--;
}
int temp = nums[l];
nums[l] = nums[k];
nums[k] = temp;
// step4: reverse between k+1, nums.length - 1
reverse(nums, k + 1, nums.length - 1);
}
return result;
}
private void reverse(int[] nums, int lb, int ub) {
while (lb < ub) {
int temp = nums[lb];
nums[lb] = nums[ub];
nums[ub] = temp;
lb++;
ub--;
}
}
下一个排列
public int[] nextPermutation(int[] nums) {
if (nums == null || nums.length <= 1) {
return nums;
}
// step1: find nums[i] < nums[i + 1]
int i = 0;
for (i = nums.length - 2; i >= 0; i--) {
if (nums[i] < nums[i + 1]) {
break;
} else if (i == 0) {
// reverse nums if reach maximum
reverse(nums, 0, nums.length - 1);
return nums;
}
}
// step2: find nums[i] < nums[j]
int j = 0;
for (j = nums.length - 1; j > i; j--) {
if (nums[i] < nums[j]) {
break;
}
}
// step3: swap betwenn nums[i] and nums[j]
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
// step4: reverse between [i + 1, n - 1]
reverse(nums, i + 1, nums.length - 1);
return nums;
}
private void reverse(int[] nums, int start, int end) {
for (int i = start, j = end; i < j; i++, j--) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
3. Combinations