当前位置:网站首页>剑指 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--);
}
}
}
边栏推荐
- A Cooperative Approach to Particle Swarm Optimization
- WGet: command line download tool
- [Arduino syntax - structure]
- Condition and AQS principle
- 【SSRF-01】服务器端请求伪造漏洞原理及利用实例
- 3D视觉——4.手势识别(Gesture Recognition)入门——使用MediaPipe含单帧(Singel Frame)和实时视频(Real-Time Video)
- 现货白银的一般操作方法
- 干货!通过软硬件协同设计加速稀疏神经网络
- Development trend of Ali Taobao fine sorting model
- 网易智企逆势进场,游戏工业化有了新可能
猜你喜欢
随机推荐
In the era of industrial Internet, we will achieve enough development by relying on large industrial categories
Paddle框架:PaddleNLP概述【飛槳自然語言處理開發庫】
LeetCode 322. Change exchange (dynamic planning)
How does Huawei enable debug and how to make an image port
Cookie concept, basic use, principle, details and Chinese transmission
什么是弱引用?es6中有哪些弱引用数据类型?js中的弱引用是什么?
How to get all sequences in Oracle database- How can I get all sequences in an Oracle database?
Basic operations of databases and tables ----- primary key constraints
伦敦银走势中的假突破
Docker compose配置MySQL并实现远程连接
leetcode刷题_验证回文字符串 Ⅱ
DOM introduction
【全網最全】 |MySQL EXPLAIN 完全解讀
servlet(1)
Spir - V premier aperçu
[the most complete in the whole network] |mysql explain full interpretation
Leetcode1961. 检查字符串是否为数组前缀
2022年广西自治区中职组“网络空间安全”赛题及赛题解析(超详细)
Tcpdump: monitor network traffic
网易智企逆势进场,游戏工业化有了新可能