击败时间100%剑指 Offer 38. 字符串的排列
Posted 来老铁干了这碗代码
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了击败时间100%剑指 Offer 38. 字符串的排列相关的知识,希望对你有一定的参考价值。
立志用最少的代码做最高效的表达
输入一个字符串,打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
示例:
输入:s = “abc”
输出:[“abc”,“acb”,“bac”,“bca”,“cab”,“cba”]
限制:
1 <= s 的长度 <= 8
核心思路:采用交换元素的方式进行递归,从而实现全排列。
优化:尽可能的将参数设置为成员变量(可以理解为全局变量),而不是放在dfs的参数中传递,后者会使效率降低。
class Solution {
List<String> res = new LinkedList<>();
char[] c;
public String[] permutation(String s) {
c = s.toCharArray();
dfs(0);
return res.toArray(new String[res.size()]);
}
void dfs(int x) {
if(x == c.length - 1) {
res.add(String.valueOf(c)); // 添加排列方案
return;
}
HashSet<Character> set = new HashSet<>(); // set去重
for(int i = x; i < c.length; i++) {
if(set.contains(c[i])) continue; // 重复,因此剪枝
set.add(c[i]);
swap(i, x); // 交换,将 c[i] 固定在第 x 位
dfs(x + 1); // 开启固定第 x + 1 位字符
swap(i, x); // 恢复交换
}
}
void swap(int a, int b) {
char tmp = c[a];
c[a] = c[b];
c[b] = tmp;
}
}
完整可执行代码
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
public class 剑指Offer38_字符串的排列 {
static class Solution {
List<String> res = new LinkedList<>();
char[] c;
public String[] permutation(String s) {
c = s.toCharArray();
dfs(0);
return res.toArray(new String[res.size()]);
}
void dfs(int x) {
if(x == c.length - 1) {
res.add(String.valueOf(c)); // 添加排列方案
return;
}
HashSet<Character> set = new HashSet<>(); // set去重
for(int i = x; i < c.length; i++) {
if(set.contains(c[i])) continue; // 重复,因此剪枝
set.add(c[i]);
swap(i, x); // 交换,将 c[i] 固定在第 x 位
dfs(x + 1); // 开启固定第 x + 1 位字符
swap(i, x); // 恢复交换
}
}
void swap(int a, int b) {
char tmp = c[a];
c[a] = c[b];
c[b] = tmp;
}
}
public static void main(String[] args) {
Solution solution = new Solution();
String[] s = solution.permutation("abc");
System.out.println(Arrays.toString(s));
}
}
以上是关于击败时间100%剑指 Offer 38. 字符串的排列的主要内容,如果未能解决你的问题,请参考以下文章