博客
关于我
Hot100之回溯算法
阅读量:793 次
发布时间: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/

你可能感兴趣的文章
8位二进制转bcd算法 c语言,二进制转BCD码快速算法 bin to bcd fast code.
查看>>
900行c语言贪吃蛇,原生js实现的贪吃蛇网页版游戏完整实例
查看>>
ado filter 多条记录_Excel 有了Filter函数VLOOKUP函数要靠边站了
查看>>
ado读取多条oracle数据,Oracle ADO数据存取
查看>>
anaconda新建python2环境安装不了jupyterlab_anaconda3安装及jupyter环境配置教程(全)...
查看>>
android asynctask handler 区别,AsyncTask与Thread+Handler简要分析
查看>>
android fastjson漏洞_初识Fastjson漏洞(环境搭建及漏洞复现)
查看>>
android进程管理策略,Android进程保活
查看>>
arduino蓝牙通讯代码_arduino 联接蓝牙模块
查看>>
asp.mvc 4项目发布文件目录结构_如何用SpringBoot(2.3.3版本)快速搭建一个项目?文末有小彩蛋...
查看>>
aspen串联反应怎么输入_如何进步提升串联谐振试验装置的稳定性
查看>>
aspose html转pdf_Java实现Word/Pdf/TXT转html
查看>>
a推b等价于非a或b_AB胶/蜜月胶常见问题的原因分析及解决方法
查看>>
bat 命令返回结果_【批处理】带你入门命令行
查看>>
c++ string取子串_Integer与String的设计哲学
查看>>
c++ 数组批量赋值_数组之间不能赋值?穿个马甲吧!
查看>>
cad模糊查询符号_mysql 正则模式和like模糊查询
查看>>
continue可以用if判断里面吗_谁能说说if()else()里的continue是干嘛的?
查看>>
ctrl c 和 ctrl v 不能用了_神奇操作,原来CTRL键还能这么用
查看>>
cytoscape安装java_Cytoscape史上最全攻略
查看>>