排列
1.有重复元素:先sort再dfs,同时加上:
if(i>0 && nums[i]==nums[i-1] && !vis[i-1]){ continue; }
2.若同一个数字可以无限制重复被选取:无vis
1.无重复元素的全排列
step、vis
class Solution {
List<List<Integer>> ans = new ArrayList<>();
List<Integer> path = new ArrayList<>();
boolean[] vis = new boolean[N];
public List<List<Integer>> permute(int[] nums) {
int n = nums.length;
dfs(n,nums,0);
return ans;
}
public void dfs(int n,int[] nums,int step){
if(step == n){
ans.add(new ArrayList<>(path));
return;
}
for(int i = 0;i<n;i++){
if(!vis[i]){
vis[i] = true;
path.add(nums[i]);
dfs(n,nums,step+1);
vis[i] = false;
path.remove(path.size()-1);
}
}
}
}
2.有重复元素的全排列
step、vis、【sort、if(!vis[i-1])】
if(i>0 && arr[i]==arr[i-1] && !vis[i-1]){ continue; }
class Solution {
List<List<Integer>> ans = new ArrayList<>();
List<Integer> path = new ArrayList<>();
boolean[] vis = new boolean[N];
public List<List<Integer>> permute(int[] nums) {
int n = nums.length;
Arrays.sort(nums);
dfs(n,nums,0);
return ans;
}
public void dfs(int n,int[] nums,int step){
if(step == n){
ans.add(new ArrayList<>(path));
return;
}
for(int i = 0;i<n;i++){
if(i>0 && nums[i]==nums[i-1] && !vis[i-1]){
continue;
}
if(!vis[i]){
vis[i] = true;
path.add(nums[i]);
dfs(n,nums,step+1);
vis[i] = false;
path.remove(path.size()-1);
}
}
}
}
组合
1.组合要用begin
2.有重复元素:先sort再dfs,同时加上:
if(i>0 && nums[i]==nums[i-1] && !vis[i-1]){ continue; }
3.若同一个数字可以无限制重复被选取:无vis
1.无重复元素的组合
step、vis、【begin】
class Solution {
List<List<Integer>> ans = new ArrayList<>();
List<Integer> path = new ArrayList<>();
boolean[] vis = new boolean[N];
public List<List<Integer>> combine(int n, int k) {
int[] arr = new int[n];
for(int i = 0;i<n;i++){
arr[i] = i+1;
}
dfs(arr,n,k,0,0);
return ans;
}
public void dfs(int[] arr,int n,int k,int begin,int step){
if(step == k){
ans.add(new ArrayList<>(path));
return;
}
for(int i = begin;i<n;i++){
if(!vis[i]){
vis[i] = true;
path.add(arr[i]);
dfs(arr,n,k,i+1,step+1);
vis[i] = false;
path.remove(path.size()-1);
}
}
}
}
2.有重复元素的组合
step、vis、【begin、sort】
if(i>0 && arr[i]==arr[i-1] && !vis[i-1]){ continue; }
class Solution {
List<List<Integer>> ans = new ArrayList<>();
List<Integer> path = new ArrayList<>();
boolean[] vis = new boolean[N];
public List<List<Integer>> combine(int n, int k) {
int[] arr = new int[n];
for(int i = 0;i<n;i++){
arr[i] = i+1;
}
Arrays.sort(arr);
dfs(arr,n,k,0,0);
return ans;
}
public void dfs(int[] arr,int n,int k,int begin,int step){
if(step == k){
ans.add(new ArrayList<>(path));
return;
}
for(int i = begin;i<n;i++){
if(i>0 && arr[i]==arr[i-1] && !vis[i-1]){
continue;
}
if(!vis[i]){
vis[i] = true;
path.add(arr[i]);
dfs(arr,n,k,i+1,step+1);
vis[i] = false;
path.remove(path.size()-1);
}
}
}
}
集合
1.集合无vis、无step(除非有要求)、要用begin
2.有重复元素:先sort再dfs,同时加上:
if(i>begin && nums[i]==nums[i-1]){ continue; }
1.无重复元素的子集
begin
class Solution {
List<List<Integer>> ans = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
int n = nums.length;
dfs(nums,n,0);
return ans;
}
public void dfs(int[] nums,int n,int begin){
ans.add(new ArrayList<>(path));
for(int i = begin;i<n;i++){
path.add(nums[i]);
dfs(nums,n,i+1);
path.remove(path.size()-1);
}
}
}
2.有重复元素的子集
begin、sort
if(i>begin && nums[i]==nums[i-1]){ continue; }
class Solution {
List<List<Integer>> ans = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) {
int n = nums.length;
Arrays.sort(nums);
dfs(nums,n,0);
return ans;
}
public void dfs(int[] nums,int n,int begin){
ans.add(new ArrayList<>(path));
for(int i = begin;i<n;i++){
if(i>begin && nums[i]==nums[i-1]){
continue;
}
path.add(nums[i]);
dfs(nums,n,i+1);
path.remove(path.size()-1);
}
}
}