代码随想录——回溯 N皇后
1.代码随想录-逆波兰式、滑动窗口最大值2.代码随想录-栈与队列-有效的括号(括号匹配)3.代码随想录——栈与队列8-前K个高频元素4.二叉树的递归遍历和迭代遍历5.代码随想录——二叉树-11.完全二叉树的节点个数6.代码随想录——二叉树-12.平衡二叉树7.代码随想录——二叉树17-路径总和8.代码随想录——二叉树19.最大二叉树9.代码随想录——二叉树21、合并二叉树(附:递归算法复杂度分析)10.代码随想录——二叉树23、验证二叉搜索树11.代码随想录——25二叉搜索树的最小绝对值差(递归遍历如何记录前后两个指针)12.代码随想录——25.二叉搜索树中的众数13.代码随想录——26、二叉(搜索)树的最近公共祖先14.代码随想录——回溯8、组合总和II15.代码随想录——回溯9.分割回文串16.代码随想录——回溯19重新安排行程
17.代码随想录——回溯 N皇后
18.代码随想录——贪心8.跳跃游戏II19.代码随想录——贪心9.K次取反后最大化的数组和 && std::sort函数的第三个参数说明20.代码随想录——贪心13.分发糖果21.代码随想录——贪心算法:根据身高重建队列 & Vector原理22.代码随想录——贪心算法22单调递增的数字23.代码随想录——贪心23监控二叉树24.代码随想录——动态规划5.周总结25.代码随想录——动态规划9不同的二叉搜索树26.代码随想录——动态规划01背包27.代码随想录——动态规划13.分割等和子集28.代码随想录——动态规划14最后一块石头的重量II(01背包)29.动态规划——dp的含义归类(完全背包和01背包区别)30.动态规划——26单词拆分31.代码随想录——动态规划背包问题总结32.代码随想录——动态规划31打家劫舍III(树状DP)33.代码随想录——动态规划、股票问题34.代码随想录——单调栈35.回溯总结
思路
每次递归都遍历第0到n-1列,判断当前位置是否合法——确保不会和之前的皇后同列、同斜线(同行已经通过递归避免了)
那么核心就是
- 怎么判断是否合法
- 怎么返回答案
2反而比较重要,因为我一开始就设了个vector<int> queen,表示第i个皇后在第queen[i]列。但这在本题不好用,之后还得根据queen再生成string数组的答案。如果返回值是vector<vector<int>> 那么可以用。
1的基础方法简单
- 本题这种string保存的就查看同列/斜线是否有‘Q’
- 如果返回int数组的,就用坐标数学关系判断:同列则纵坐标相同,同斜线则 abs(横坐标差)=abs(纵坐标差)
但以上方法是O(N)的复杂度,还可以优化为O(1)。本次暂时不写。
代码
下面是两种返回类型的答案
vector<vector<string>>
class Solution {
public:
vector<vector<string>> result;
void backtracking(vector<string>& queen,int n,int k){
if(k == n){
result.emplace_back(queen);
return;
}
for(int col=0;col<n;col++){//遍历第k行第col列
if(isValid(k,col,queen,n)){
queen[k][col] = 'Q';
backtracking(queen,n,k+1);
queen[k][col] = '.';
}
}
}
bool isValid(int row,int col,vector<string>& queen,int n){
//检查列
for(int i=0;i<row;i++){
if(queen[i][col] == 'Q')return false;
}
//检查左斜线
for(int i=row-1,j=col+1;i>=0 && j<n;i--,j++){
if(queen[i][j] == 'Q')return false;
}
//检查右斜线
for(int i=row-1,j=col-1;i>=0 && j>=0;i--,j--){
if(queen[i][j] == 'Q')return false;
}
return true;
}
vector<vector<string>> solveNQueens(int n) {
// vector<int> queen(n);//第0个皇后(一定在第0行)在第queen[0]列
result.clear();
vector<string> queen(n,string(n,'.'));
backtracking(queen,n,0);
return result;
}
};
vector<vector<int>>
class Solution {
public:
vector<vector<int>> result; // 存储所有的解,每个解是一个位置数组
void backtracking(int n, int row, vector<int>& queen) {
if (row == n) { // 所有皇后都放置完成
result.push_back(queen); // 将当前解添加到结果中
return;
}
for (int col = 0; col < n; col++) {
if (isValid(row, col, queen)) {
queen[row] = col; // 将第row行的皇后放在col列
backtracking(n, row + 1, queen); // 递归放置下一个皇后
queen[row] = -1; // 回溯,撤销当前放置的皇后
}
}
}
bool isValid(int row, int col, const vector<int>& queen) {
for (int i = 0; i < row; i++) {
// 检查列冲突
if (queen[i] == col) return false;
// 检查斜线冲突
if (abs(queen[i] - col) == abs(i - row)) return false;
}
return true;
}
vector<vector<int>> solveNQueens(int n) {
result.clear();
vector<int> queen(n, -1); // 用来存储皇后的位置,-1表示尚未放置
backtracking(n, 0, queen);
return result;
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!