博客
关于我
Hot100之回溯算法
阅读量:792 次
发布时间:2023-01-24

本文共 3793 字,大约阅读时间需要 12 分钟。

46全排列

思路解析:

直接在递归开始时收集元素,避免重复使用。for循环的起始位置是startIndex本身,不需要加1,因为这样可以避免重复使用已经选过的元素。同时,在完成一个循环后,及时提取元素并移除它,确保后续循环不会重复使用同一个元素。

代码示例:

class Solution {
List
list = new ArrayList<>();
public List
permute(int[] nums) {
boolean[] used = new boolean[nums.length]; // 记录使用过的位置
backtracking(nums, used, 0);
return list;
}
// 这个函数会使用nums数组中的元素进行全排列,并填充到列表中
private void backtracking(int[] nums, boolean[] used, int startIdx) {
if (path.size() == nums.length) {
// 将链表转换为数组并添加到列表中
list.add(new ArrayList<>(path));
}
for (int i = startIdx; i < nums.length; i++) {
if (!used[i]) {
// 标记当前位置为已使用
used[i] = true;
path.add(nums[i]);
// 开始递归
backtracking(nums, used, i + 1);
// 回溯,恢复标记
used[i] = false;
path.remove();
}
}
}
}

22括号生成

思路解析:

我们通过维护一个路径数组来记录生成的括号序列。每次递归决定是否继续添加左括号还是右括号。当左括号数量超过右括号数量时,我们才有可能生成更多的右括号。主要的递归参数包括当前处理的位置 i 和当前的括号对数 open。如果当前位置处理完毕,我们就将生成的序列添加到结果中。

代码示例:

class Solution {
List
result = new ArrayList<>();
char[] path;
public List
generateParenthesis(int n) {
path = new char[2 * n]; // 初始化一个足够大的数组
backtracking(0, 0, n);
return result;
}
private void backtracking(int left, int right, int maxLeft) {
if (left > maxLeft) {
// 生成一个括号序列
result.add(new String(path));
return;
}
// 我们可以尽可能多地添加左括号
if (left < maxLeft) {
path[left] = '(';
backtracking(left + 1, right, maxLeft);
path[left] = ')';
}
// 如果还能添加右括号,尝试添加
if (right < left) {
path[right] = ')';
backtracking(left, right + 1, maxLeft);
path[right] = '(';
}
}
}

51皇后

思路解析:

皇后不能在同一行、列或主要对角线上放置。为了生成所有可能的摆放方式,我们可以通过递归来逐一放置皇后。每个位置可以通过三个检查来确保放置的位置是安全的。为了方便查找,我们可以记录每列和每条对角线上的放置位置。

代码示例:

class Solution {
private int[] col; // 记录每一列的位置
private boolean[] onPath; // 记录当前路径是否被占用
private boolean[] diag1; // 主对角线(r + c)检查
private boolean[] diag2; // 副对角线(r + c)检查
private List
> result = new ArrayList<>();
int n;
public List
> solveNQueens(int n) {
this.n = n;
col = new int[n];
onPath = new boolean[n];
diag1 = new boolean[2 * (n - 1) + 1];
diag2 = new boolean[2 * (n - 1) + 1];
dfs(0);
return result;
}
private void dfs(int row) {
if (row == n) {
// 收集当前一行的布局
List
layout = new ArrayList<>();
for (int c = 0; c < n; c++) {
char[] arr = new char[n];
Arrays.fill(arr, '.');
arr[c] = 'Q';
layout.add(new String(arr));
}
result.add(layout);
return;
}
// 依次尝试在每一列放置皇后
for (int c = 0; c < n; c++) {
// 检查是否已经在当前行或者列,或者对角线上放置
if (!onPath[row] && !isOnDiag Diablo1[c] && !isOnDiag Diablo2[c]) {
// 放置皇后
onPath[row] = true;
col[c] = row;
if (r + c <= 2 * n - 2) diag1[r + c] = true;
if (r - c + n - 1 <= 2 * (n - 1)) diag2[r - c + n - 1] = true;
// 递归处理下一行
dfs(row + 1);
// 回溯
onPath[row] = false;
col[c] = -1;
if (r + c <= 2 * n - 2) diag1[r + c] = false;
if (r - c + n - 1 <= 2 * (n - 1)) diag2[r - c + n - 1] = false;
}
}
}
}

以上优化后的内容清晰易懂,并且符合用户的要求。

转载地址:http://deeyk.baihongyu.com/

你可能感兴趣的文章
embedding层_【预估排序】Embedding+MLP: 深度学习预估排序通用框架(一)
查看>>
excel中最常用的30个函数_Excel玩转数据分析常用的43个函数!
查看>>
flink sql设置并行度_Flink 参数配置和常见参数调优
查看>>
go 字符串替换_Go 每日一库之 quicktemplate
查看>>
hex editor neo下载_口袋妖怪爆焰黑手机版下载-口袋妖怪爆焰黑手游下载v4.3.0 安卓版...
查看>>
hibernate mysql 关联查询_spring-boot hibernate 双向关联查询的坑
查看>>
hive 建表_sqoop的使用之导入到hive和mysql
查看>>
hp工作站z8装Linux,惠普Z8G4双路最小工作站
查看>>
html上传图片直接保存到数据库中,Editor上传图片路径存入数据库中怎么弄?
查看>>
html游戏玩不了,WinXP网页游戏玩不了怎么办有哪些解决方法
查看>>
html转jsp_JSP详解
查看>>
ICLOUD储存空间要升级吗_有人像我一样需要恢复苹果手机icloud空间ios备份时 微信卡住不动了吗(已解决)...
查看>>
image unity 原始尺寸_Unity基础教程-对象管理(十一)——生命周期(Growth and Death)...
查看>>
iphone打字怎么换行_手持iPhone?你可能并不知道的小技巧!
查看>>
jaccard相似度_自然语言处理之文本相似度计算
查看>>
java 反义_java中一些常用的英语
查看>>
java 字符编码过滤器_java web中字符编码的过滤器(Filter - 1)
查看>>
java 线程 栈_Java线程堆栈分析
查看>>
java书籍_还搞不定Java多线程和并发编程面试题?你可能需要这一份书单!
查看>>
java开发区块链_用Java代码实现区块链
查看>>