面试题 08.08. 有重复字符串的排列组合--回溯算法
LeetCode
面试题 08.08. 有重复字符串的排列组合 有重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合
示例1:
输入:S = "qqe"
输出:["eqq","qeq","qqe"]
示例2:
输入:S = "ab"
输出:["ab", "ba"]
解法:回溯法 解题思路: 首先,要求一个字符串的各种组合,我们第一个想法肯定是通过for循环,那么for循环的层数是多少勒,应该是该字符串的长度,然后通过for循环来进行匹配,但是,我们应该要注意一个问题,在进行排列组合的时候,可能会出现重复的字符串,比如说
【面试题 08.08. 有重复字符串的排列组合--回溯算法】字符串
S = aa
我们的for循环代码是这样的
for(int i=0;
i<2;
i++)
for(int j=0;
j<2;
j++)
if(i!=j)
printf("%c%c\n",S[i],S[j]);
这时候,输出结果是这样的
aa
aa
也就是说会出现重复,所以我们发现了,在一层循环中,相同的字符会产生出相同的字符串,因此我们会对上面的代码这样修改
for(int i=0;
i<2;
i++)
{
if(i>0 && S[i]==S[i-1])
continue
for(int j=0;
j<2;
j++)
{
if(j>0 && S[j]==S[j-1] && j-1!=i) //j-1!=i表示上一个字符并没有被前面一层循环使用时
continue;
if(i!=j)
printf("%c%c\n",S[i],S[j]);
}
}
这样输出结果就是
aa
根据这一思路,我们就可以用递归来解决这个问题,首先,我们要定义
boolean used[] //表示一个字符是否被使用,因为是在递归里,不能像for循环一样来规避相同位置的元素
完整代码:
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
class Solution {
public String[] permutation(String S) {
List res = new ArrayList();
int len = S.length();
if (len == 0) return new String[0];
boolean[] used = new boolean[len];
char[] sChar = S.toCharArray();
StringBuilder path = new StringBuilder(len);
// 排序是为了后面的剪枝。其实剪枝就是我们for循环里边避免重复操作的那一步
Arrays.sort(sChar);
dfs(res, sChar, len, path, 0, used);
return res.toArray(new String[0]);
}/**
* @param res 结果集
* @param sChar 输入字符数组
* @param len 字符数组长度
* @param path 根结点到任意结点的路径
* @param depth 当前树的深度
* @param used 使用标记数组
*/
private void dfs(List res
, char[] sChar
, int len
, StringBuilder path
, int depth
, boolean[] used) {
// 到达叶子结点
if (depth == len) {
res.add(path.toString());
return;
}for (int i = 0;
i < len;
i++) {
if (!used[i]) {// 根据已排序字符数组, 剪枝
if (i > 0 && sChar[i] == sChar[i-1] && !used[i-1]) {
continue;
}path.append(sChar[i]);
used[i] = true;
// 标记选择
dfs(res, sChar, len, path, depth+1, used);
path.deleteCharAt(depth);
used[i] = false;
// 撤销选择
}
}
}
}
解法来源 作者:miracle-131
链接:https://leetcode-cn.com/problems/permutation-ii-lcci/solution/hui-su-suan-fa-jian-zhi-9980-10000-by-miracle-131/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
推荐阅读
- PMSJ寻平面设计师之现代(Hyundai)
- 杜月笙的口才
- Linux下面如何查看tomcat已经使用多少线程
- 皮夹克
- 解读《摩根集团》(1)
- 绘本与写作
- 蓝桥杯试题
- 麦田社群
- 面对苦难——如何化解
- 葱爷说股20190107