1.全排列
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案
import java.util.ArrayList;
import java.util.List;
public class Solution {
public void persum(int []nums){
//数组长度
int len=nums.length;
//用一个boolean数组判断位置是否可用
boolean user[]=new boolean[len];
//保存访问的路线
ArrayList<Integer> path = new ArrayList<>();
def2(nums,len,0,path,user);
}
public void def2(int []nums,int len,int depth,ArrayList<Integer>path,boolean []user){
//深度depth递归到第几层,递归到len层就输出
if(depth==len){
for (Integer list :path) {
System.out.print(list+" ");
}
System.out.println();
return;
}
for (int i = 0; i <len ; i++) {
if(!user[i]){
path.add(nums[i]);
user[i]=true;
//深层递归后续的排列顺序,1-2-3 1放进去,就只考虑2-3的排列顺序
def2(nums,len,depth+1,path,user);
path.remove(path.size()-1);
user[i]=false;
}
}
}
public static void main(String[] args) {
int[] nums = {1, 2, 3};
Solution solution = new Solution();
solution.persum(nums);
// List<List<Integer>> lists = solution.permute(nums);
// System.out.println(lists);
}
}
2.全排列去重
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Solution2 {
public void permuteUnique(int []nums){
int len=nums.length;
ArrayList<Integer> path = new ArrayList<Integer>();
boolean[] user = new boolean[len];
def(nums,len,0,user,path);
}
public void def(int num[],int len,int depth,boolean []user, ArrayList<Integer>path){
if(depth==len){
for(Integer list:path){
System.out.print(list+"");
}
System.out.println();
return;
}
for (int i = 0; i <len ; i++) {
//搜索起点和上一次的搜索的起点一样,1还未使用过,1~的搜索结果肯定和1一样
//写 !used[i - 1] 是因为 nums[i - 1] 在深度优先遍历的过程中刚刚被撤销选择
if(i>0 && num[i]==num[i-1] && !user[i-1]){
continue;
}
if(!user[i]){
path.add(num[i]);
user[i]=true;
def(num,len,depth+1,user,path);
path.remove(path.size()-1);
user[i]=false;
}
}
}
public static void main(String[] args) {
int[] nums = {1, 1,1, 2};
Solution2 solution2 = new Solution2();
solution2.permuteUnique(nums);
}
}
组合总数
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Solution3 {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
ArrayList<Integer> path = new ArrayList<>();
Arrays.sort(candidates);
int len = candidates.length;
dfs(candidates,0,target,path,res);
return res;
}
public void dfs(int [] nums,int begin,int target,ArrayList<Integer>path, List<List<Integer>> res){
if(target==0)
{
res.add(new ArrayList<>(path));
return;
}
//每一次搜索的时候设置 下一轮搜索的起点 begin
for (int i = begin; i <nums.length ; i++) {
// 重点理解这里剪枝,前提是候选数组已经有序,
if(target-nums[i]<0)
break;
path.add(nums[i]);
//注意:由于每一个元素可以重复使用,下一轮搜索的起点依然是 i,这里非常容易弄错
dfs(nums,i,target-nums[i],path,res);
path.remove(path.size()-1);
}
}
public static void main(String[] args) {
int nums[]={2,3,6,7};
int target=7;
Solution3 solution3 = new Solution3();
List<List<Integer>> lists = solution3.combinationSum(nums, target);
System.out.println(lists);
}
}