最近刷了一波排列组合以及子集问题 主要学会理解for循环中 i 与 pos 以及level的这些变量的理解
这个可以从递归树来判别
#题目:排列
Given a collection of distinct numbers, return all possible permutations.
For example,
[1,2,3] have the following permutations:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
并不用考虑重复
主要是看 递归树图
上代码:
public ArrayList<ArrayList<Integer>> Permutation(int[] nums){
ArrayList<ArrayList<Integer>> arrs = new ArrayList<>();
ArrayList<Integer> arr = new ArrayList<>();
helper(nums,0,arr,arrs);
return arrs;
}
/*
* 简单地说:就是第一个数分别以后面的数进行交换
*E.g:E = (a , b , c),则 prem(E)= a.perm(b,c)+ b.perm(a,c)+ c.perm(a,b)
*然后a.perm(b,c)= ab.perm(c)+ ac.perm(b)= abc + acb.依次递归进行
*/
public void helper(int[] nums,int pos,ArrayList<Integer> arr,ArrayList<ArrayList<Integer>> arrs){
if(pos == nums.length){
//这是正确的写法
arr = new ArrayList<>();
for (int i = 0; i < nums.length; i++) {
arr.add(nums[i]);
}
arrs.add(arr);
}else{
/**
* 我觉得过程是这样的
* perm(a,b,c) = a+perm(b,c)(pos = 0 取出a) =
*/
for (int i = pos; i < nums.length; i++) { //pos表示
swap(nums,i,pos); //pos表示当前数
helper(nums,pos+1,arr,arrs); //当前pos位置确定,在pos位置后面继续全排列
swap(nums,i,pos); //还原到原来的数组
}
}
}
private void swap(int[] nums,int i,int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
#题目:子集
Given a set of distinct integers, nums, return all possible subsets.
Note: The solution set must not contain duplicate subsets.
For example,
If nums = [1,2,3], a solution is:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
并不用考虑重复
上代码:
public ArrayList<ArrayList<Integer>> subsetByDfs(int[] nums){
ArrayList<ArrayList<Integer>> arrs = new ArrayList<>();
ArrayList<Integer> arr = new ArrayList<>();
helperByDfs(nums,arrs,arr,0);
return arrs;
}
private void helperByDfs(int[] nums,ArrayList<ArrayList<Integer>> arrs,
ArrayList<Integer> arr,int pos){
arrs.add(new ArrayList<>(arr));
for (int i = pos; i < nums.length; i++) {
arr.add(nums[i]);
helperByDfs(nums,arrs,arr,i+1);
arr.remove(arr.size()-1);
}
}
#题目:组合
Given two integers n and k, return all possible combinations of k numbers out of 1 … n.
For example,
If n = 4 and k = 2, a solution is:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
并不用考虑重复
上代码:
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> arrs = new ArrayList<>();
ArrayList<Integer> arr = new ArrayList<>();
int[] nums = new int[n];
for (int i = 0; i < nums.length; i++) {
nums[i] = i+1;
}
Dfs(nums,arrs,arr,0,k,0);
return arrs;
}
public void Dfs(int[] nums,List<List<Integer>> arrs,List<Integer> arr,int level,int k,int pos){
if(level==k){
arrs.add(new ArrayList<>(arr));
return;
}
for (int i = pos; i < nums.length; i++) {
arr.add(nums[i]);
Dfs(nums, arrs, arr, level+1, k, i+1);
arr.remove(arr.size()-1);
}
}