一、有重复字符串的排列组合
1、题目描述:有重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合。
2、示例如下:
3、代码如下:
class Solution {
LinkedList<String> list=new LinkedList<>();
public String[] permutation(String S) {
dfs(S.toCharArray(),0);
return list.toArray(new String[0]);
}
public void dfs(char[] c,int k){ //k表示在第几层,即有几个字符确定排列
if(k==c.length){ //确定一次深度递归终止的条件
list.add(new String(c));
return ;
}
HashSet<Character> set=new HashSet<>();
for(int i=k;i<c.length;i++){ //在第k层,有max-k个选择
if(!set.contains(c[i])){ //判断是否有重复元素
set.add(c[i]);
swap(c,i,k); //换一条道继续深入
dfs(c,k+1); //进入下一层,即确定一个字符
swap(c,i,k); //换回来,保证后续按正常遍历搜索
}
}
}
public void swap(char[] c,int x,int y){
char temp=c[x];
c[x]=c[y];
c[y]=temp;
}
}
二、数字组合
1、题目描述:给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。
2、示例如下:
3、代码如下:
class Solution {
List<List<Integer>> list=new ArrayList<List<Integer>>();
List<Integer> temp=new ArrayList<Integer>();
public List<List<Integer>> combine(int n, int k) {
dfs(1,n,k);
return list;
}
public void dfs(int cur,int n,int k){ //k表示在第几层,即有几个字符确定排列
// 剪枝:temp 长度加上区间 [cur, n] 的长度小于 k,不可能构造出长度为 k 的 temp
//简单来说就是如果确定和未确定的数字数量相加小于k就没必要继续进行下去了
if (temp.size() + (n - cur + 1) < k) {
return;
}
if(temp.size()==k){ //确定一次深度递归终止的条件
list.add(new ArrayList<Integer>(temp)); //确定一个新的合法对象
return;
}
temp.add(cur); //确定当前的数字
dfs(cur+1,n,k); //选择下一个数字
temp.remove(temp.size()-1); //去掉新确定的数字
dfs(cur+1,n,k); //换一个数字
}
}