当前位置:网站首页>剑指 Offer 38. 字符串的排列
剑指 Offer 38. 字符串的排列
2022-07-06 01:28:00 【Yake1965】
剑指 Offer 38. 字符串的排列
回溯:决策当前字符串的某一位填入什么字符。
去重通用方法:
- 使用 Set 实现去重;
- 先对原字符串进行排序,然后确保相同字符传入同一目标位置的动作只发生一次。
方法一: Set 去重
只对结果去重,没有去除重复计算。42 ms
class Solution {
Set<String> set = new HashSet<>();
char[] arr;
boolean[] vis;
public String[] permutation(String s) {
arr = s.toCharArray();
vis = new boolean[arr.length];
backtrack(0, "");
return set.toArray(String[]::new);
}
void backtrack(int idx, String t){
if(idx == arr.length) {
set.add(t);
return;
}
for(int i = 0; i < arr.length; i++){
if(vis[i]) continue;
vis[i] = true;
backtrack(idx + 1, t + arr[i]);
vis[i] = false; // 回溯
}
}
}
逐位去重 21 ms
class Solution {
List<String> list = new ArrayList<>();
char[] arr;
boolean[] vis;
public String[] permutation(String s) {
arr = s.toCharArray();
vis = new boolean[arr.length];
backtrack(0, "");
return list.toArray(String[]::new);
}
void backtrack(int idx, String t){
if(idx == arr.length) {
list.add(t);
return;
}
Set<Character> set = new HashSet<>(); // 去重
for(int i = 0; i < arr.length; i++){
if(vis[i] || set.contains(arr[i])) continue;
vis[i] = true;
set.add(arr[i]);
backtrack(idx + 1, t + arr[i]);
vis[i] = false;
}
}
}
通过交换遍历 6 ms
class Solution {
List<String> list = new ArrayList<>();
char[] arr;
public String[] permutation(String s) {
arr = s.toCharArray();
backtrack(0);
return list.toArray(String[]::new);
}
void backtrack(int idx){
if(idx == arr.length - 1) {
list.add(new String(arr)); // String.valueOf(arr)
return;
}
Set<Character> set = new HashSet<>();
for(int i = idx; i < arr.length; i++){
if(set.contains(arr[i])) continue;
set.add(arr[i]);
swap(i, idx); // 当前位分别替换成后面的其它字母
backtrack(idx + 1);
swap(idx, i);
}
}
void swap(int i, int j){
char tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp;
}
}
方法二:排序去重
class Solution {
List<String> list = new ArrayList<>();
char[] arr;
boolean[] vis;
public String[] permutation(String s) {
arr = s.toCharArray();
vis = new boolean[arr.length];
Arrays.sort(arr);
backtrack(0, "");
return list.toArray(String[]::new);
}
void backtrack(int idx, String t){
if(idx == arr.length) {
list.add(t);
return;
}
for(int i = 0; i < arr.length; i++){
if(vis[i] || i > 0 && !vis[i-1] && arr[i] == arr[i-1]) continue;
vis[i] = true;
backtrack(idx + 1, t + String.valueOf(arr[i]));
vis[i] = false;
}
}
}
47.全排列II
class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
def backtrack(depth=0, path=[]):
if depth == n:
res.append(path[:])
return
for i in range(n):
if used[i] or (i > 0 and nums[i] == nums[i - 1] and used[i - 1]): continue
path.append(nums[i])
used[i] = True
backtrack(depth + 1, path)
path.pop()
used[i] = False
def backtrack1(depth=0):
if depth == n: res.append(nums[:])
for i in range(depth, n):
nums[depth], nums[i] = nums[i], nums[depth]
backtrack1(depth + 1)
nums[depth], nums[i] = nums[i], nums[depth]
## 深度优先搜索
def dfs(depth=0, path=[], tmp=nums):
if depth == n:
res.append(path)
return
for i in range(len(tmp)):
dfs(depth + 1, path + [tmp[i]], tmp[:i] + tmp[i + 1:])
n, res = len(nums), []
nums.sort()
used = [False] * n
backtrack()
# backtrack1()
# dfs()
return res
# return list(set(permutations(nums)))
class Solution {
boolean[] vis;
List<List<Integer>> ans = new ArrayList<List<Integer>>();
List<Integer> perm = new ArrayList<Integer>();
public List<List<Integer>> permuteUnique(int[] nums) {
vis = new boolean[nums.length];
Arrays.sort(arr);
backtrack(0, nums);
return ans;
}
public void backtrack(int idx, int[] arr){
if (idx == arr.length) {
ans.add(new ArrayList<Integer>(perm));
return;
}
for (int i = 0; i < arr.length; ++i) {
if (vis[i] || i > 0 && arr[i] == arr[i-1] && !vis[i-1]) continue; // !used[i-1] 比 used[i-1] 快点
perm.add(arr[i]);
vis[i] = true;
backtrack(idx + 1, arr);
vis[i] = false;
perm.remove(idx);
}
}
}
class Solution {
List<List<Integer>> ans;
public List<List<Integer>> permuteUnique(int[] nums) {
ans = new LinkedList<>();
backtrack(0, nums);
return ans;
}
void backtrack(int idx, int[] arr) {
if (idx == arr.length) {
// ans.add(Arrays.stream(arr).boxed().toList());
List<Integer> tmp = new ArrayList<>();
for(int i = 0; i < arr.length; i++) tmp.add(arr[i]);
ans.add(tmp);
return;
}
Set<Integer> set = new HashSet<>();
for (int j = idx; j < arr.length; j++) {
if (!set.contains(arr[j])) {
set.add(arr[j]);
swap(arr, j, idx);
backtrack(idx + 1, arr);
swap(arr, j, idx);
}
}
}
void swap(int[] nums, int i, int j) {
int tmp = nums[i]; nums[i] = nums[j]; nums[j] = tmp;
}
}
方法三:31. 下一个排列
class Solution {
public String[] permutation(String s) {
List<String> ans = new ArrayList<String>();
char[] arr = s.toCharArray();
Arrays.sort(arr);
do {
ans.add(new String(arr));
} while (nextPermutation(arr));
return ans.toArray(String[]::new);
}
boolean nextPermutation(char[] arr) {
int i = arr.length - 2;
while (i >= 0 && arr[i] >= arr[i + 1]) i--;
if (i < 0) return false;
int j = arr.length - 1;
while (j >= 0 && arr[i] >= arr[j]) j--;
swap(arr, i, j);
reverse(arr, i + 1);
return true;
}
void swap(char[] arr, int i, int j) {
char temp = arr[i]; arr[i] = arr[j]; arr[j] = temp;
}
void reverse(char[] arr, int left) {
int right = arr.length - 1;
while (left < right) {
swap(arr, left++, right--);
}
}
}
31. 下一个排列
class Solution {
public void nextPermutation(int[] nums) {
int i = nums.length - 2;
while (i >= 0 && nums[i] >= nums[i + 1]) i--;
if (i < 0){
reverse(nums, 0);
return;
}
int j = nums.length - 1;
while (j >= 0 && nums[i] >= nums[j]) j--;
swap(nums, i, j);
reverse(nums, i + 1);
return;
}
void swap(int[] arr, int i, int j) {
int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp;
}
void reverse(int[] arr, int left) {
int right = arr.length - 1;
while (left < right) {
swap(arr, left++, right--);
}
}
}
边栏推荐
- Basic process and testing idea of interface automation
- Superfluid_ HQ hacked analysis
- Ordinary people end up in Global trade, and a new round of structural opportunities emerge
- NLP第四范式:Prompt概述【Pre-train,Prompt(提示),Predict】【刘鹏飞】
- Mysql--- query the top 5 students
- [Jiudu OJ 09] two points to find student information
- 电气数据|IEEE118(含风能太阳能)
- In the era of industrial Internet, we will achieve enough development by relying on large industrial categories
- A picture to understand! Why did the school teach you coding but still not
- 一图看懂!为什么学校教了你Coding但还是不会的原因...
猜你喜欢

一圖看懂!為什麼學校教了你Coding但還是不會的原因...

Leetcode skimming questions_ Sum of squares

Huawei Hrbrid interface and VLAN division based on IP

Pbootcms plug-in automatically collects fake original free plug-ins

Basic operations of databases and tables ----- unique constraints

Unity | two ways to realize facial drive

Basic process and testing idea of interface automation

【Flask】官方教程(Tutorial)-part2:蓝图-视图、模板、静态文件

A Cooperative Approach to Particle Swarm Optimization

Dede collection plug-in free collection release push plug-in
随机推荐
ctf. Show PHP feature (89~110)
Netease smart enterprises enter the market against the trend, and there is a new possibility for game industrialization
黄金价格走势k线图如何看?
MUX VLAN configuration
A Cooperative Approach to Particle Swarm Optimization
Tcpdump: monitor network traffic
普通人下场全球贸易,新一轮结构性机会浮出水面
C web page open WinForm exe
【详细】快速实现对象映射的几种方式
网易智企逆势进场,游戏工业化有了新可能
Leetcode skimming questions_ Verify palindrome string II
Electrical data | IEEE118 (including wind and solar energy)
About error 2003 (HY000): can't connect to MySQL server on 'localhost' (10061)
MySQL learning notes 2
【SSRF-01】服务器端请求伪造漏洞原理及利用实例
【Flask】静态文件与模板渲染
Opinions on softmax function
干货!通过软硬件协同设计加速稀疏神经网络
Hcip---ipv6 experiment
Three methods of script about login and cookies