参考链接:https://leetcode-cn.com/problems/permutations-ii/solution/hui-su-suan-fa-python-dai-ma-java-dai-ma-by-liwe-2/
给定一个 没有重复 数字的序列,返回其所有可能的全排列。
参考链接
https://leetcode-cn.com/problems/permutations/solution/hui-su-suan-fa-python-dai-ma-java-dai-ma-by-liweiw/
整个流程类似于一个棵决策树的遍历,采用深度优先搜索策略。在实现的时候主要有两点需要注意
List> res; // 记录path的集合
public List> permute(int[] nums) {
// 空值处理
if(nums.length==0)
return new ArrayList<>();
int len = nums.length;
res = new ArrayList<>();
List path = new ArrayList();
boolean[] used = new boolean[len]; // 记录是否访问过
dfs(nums, len, 0, path, used);
return res;
}
public void dfs(int[] nums, int len, int depth, List path, boolean[] used){
if(depth==len)
res.add(new ArrayList(path)); // 拷贝一个对象添加到res集合中
// 搜索数组中访问的数值
for(int i=0; i
给定一个可包含重复数字的序列,返回所有不重复的全排列。
这道题目与第一道题目的区别在于,在暴力所有所有情况,存在很多重复的排列。解题方法,在第一提的基础上,考虑如何去重。这里为了去重做了两件事情
if(i>0&&nums[i]==nums[i-1]&&used[i-1]==false
判断来筛选、过滤掉相等数值区间除了第一个数值之外的数值。至于排序去重的作用,大佬做出了解释。
 {
res = new ArrayList<>();
int len = nums.length;
List path = new ArrayList();
boolean[] used = new boolean[len];
Arrays.sort(nums); // 排序
dfs(nums, len, 0, path, used);
return res;
}
public void dfs(int[] nums, int len, int depth, List path, boolean[] used){
if(nums.length==depth){
res.add(new ArrayList(path));
return;
}
for(int i=0; i0&&nums[i]==nums[i-1]&&used[i-1]==false)
continue;
path.add(nums[i]);
used[i]=true;
dfs(nums, len, depth+1, path, used);
path.remove(path.size()-1);
used[i]=false;
}
}
}
输入一个字符串,打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
示例:
输入:s = “abc”
输出:[“abc”,“acb”,“bac”,“bca”,“cab”,“cba”]
这道题目本质上与上面一题一样,是找出包含相同元素的排列问题
,与上面题目的区别在于,这里需要排列的是字符。
public List res = new ArrayList<>();
public String[] permutation(String s) {
// 空值处理
if(s.isEmpty())
return new String[0];
// 字符串转成字符数组,便于随机访问
char[] charArray = s.toCharArray();
int len = charArray.length;
// path定义为字符串构造器,便于修改字符
StringBuilder path = new StringBuilder();
boolean[] used = new boolean[len];
// 为了便于去重
Arrays.sort(charArray);
dfs(charArray, len, 0, path, used);
return res.toArray(new String[0]); // list转成字符串数组
}
public void dfs(char[] charArray, int len, int depth, StringBuilder path, boolean[] used){
// 越过叶子节点时,输出path到res
if(depth==len){
res.add(path.toString());
}
// 遍历未访问过的节点
for(int i=0; i0&&charArray[i]==charArray[i-1]&&used[i-1]==false)
continue;
path.append(charArray[i]);
used[i] = true;
dfs(charArray, len, depth+1, path, used);
path.deleteCharAt(path.length()-1);
used[i] = false;
}
}
}