[Leetcode][第81题][JAVA][N皇后问题][回溯算法]

【问题描述】[困难]

在这里插入图片描述

【解答思路】

在这里插入图片描述

1. 主副对角线列 标记

在这里插入图片描述

复杂度
在这里插入图片描述

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;public class Solution {private int n;// 记录某一列是否放置了皇后private boolean[] col;// 记录主对角线上的单元格是否放置了皇后private boolean[] main;// 记录了副对角线上的单元格是否放置了皇后private boolean[] sub;private List<List<String>> res;public List<List<String>> solveNQueens(int n) {res = new ArrayList<>();if (n == 0) {return res;}// 设置成员变量,减少参数传递,具体作为方法参数还是作为成员变量,请参考团队开发规范this.n = n;this.col = new boolean[n];this.main = new boolean[2 * n - 1];this.sub = new boolean[2 * n - 1];Deque<Integer> path = new ArrayDeque<>();dfs(0, path);return res;}private void dfs(int row, Deque<Integer> path) {if (row == n) {// 深度优先遍历到下标为 n,表示 [0.. n - 1] 已经填完,得到了一个结果List<String> board = convert2board(path);res.add(board);return;}// 针对下标为 row 的每一列,尝试是否可以放置for (int j = 0; j < n; j++) {if (!col[j] && !main[row + j] && !sub[row - j + n - 1]) {path.addLast(j);col[j] = true;main[row + j] = true;sub[row - j + n - 1] = true;dfs(row + 1, path);// 递归完成以后,回到之前的结点,需要将递归之前所做的操作恢复sub[row - j + n - 1] = false;main[row + j] = false;col[j] = false;path.removeLast();}}}private List<String> convert2board(Deque<Integer> path) {List<String> board = new ArrayList<>();for (Integer num : path) {StringBuilder row = new StringBuilder();row.append(".".repeat(Math.max(0, n)));row.replace(num, num + 1, "Q");board.add(row.toString());}return board;}
}

其实已经摆放皇后的列下标、占据了哪一条主对角线、哪一条副对角线也可以使用哈希表来记录。

实际上哈希表底层也是数组,使用哈希表可以不用处理已经占据位置的皇后的主对角线、副对角线的下标偏移问题。

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashSet;
import java.util.List;
import java.util.Set;public class Solution {private Set<Integer> col;private Set<Integer> main;private Set<Integer> sub;private int n;private List<List<String>> res;public List<List<String>> solveNQueens(int n) {this.n = n;res = new ArrayList<>();if (n == 0) {return res;}col = new HashSet<>();main = new HashSet<>();sub = new HashSet<>();Deque<Integer> path = new ArrayDeque<>();dfs(0, path);return res;}private void dfs(int row, Deque<Integer> path) {if (row == n) {List<String> board = convert2board(path);res.add(board);return;}// 针对每一列,尝试是否可以放置for (int i = 0; i < n; i++) {if (!col.contains(i) && !main.contains(row + i) && !sub.contains(row - i)) {path.addLast(i);col.add(i);main.add(row + i);sub.add(row - i);dfs(row + 1, path);sub.remove(row - i);main.remove(row + i);col.remove(i);path.removeLast();}}}private List<String> convert2board(Deque<Integer> path) {List<String> board = new ArrayList<>();for (Integer num : path) {StringBuilder row = new StringBuilder();row.append(".".repeat(Math.max(0, n)));row.replace(num, num + 1, "Q");board.add(row.toString());}return board;}
}
2. board[n][n]标记 直接遍历

时间复杂度:O(N!) 空间复杂度:O(N2)

class Solution {List<List<String>> res=new ArrayList<>();public List<List<String>> solveNQueens(int n) {//棋盘,默认为0表示空,1表示皇后int[][] borad = new int[n][n];//row当前填写得的行号dfs(n,0,borad);return res;}public void dfs(int n,int row,int[][] board) { if (row == n) { // n个棋子都放置好了,打印结果 res.add(track(board,n));// n行棋子都放好了,已经没法再往下递归了,所以就return } return; }for (int column = 0; column < n; ++column) { // 每一行都有8中放法 if (isOk(row, column,n,board)) { // 有些放法不满足要求             board[row][column] =1; dfs( n,row+1,board); // 考察下一行board[row][column] =0;} }}private boolean isOk(int row ,int column ,int n,int[][] board){int leftup = column -1,rightup = column+1;for(int i=row-1;i>=0;i--){// 逐行往上考察每一行if(board[i][column]==1){// 第i行的column列有棋子吗?return false;}if(leftup>=0){// 考察左上对角线:第i行leftup列有棋子吗?if(1==board[i][leftup])return false;}if(rightup<n){// 考察右上对角线:第i行rightup列有棋子吗?if(1==board[i][rightup])return false;}leftup--;rightup++;}return true;}private List<String> track(int[][] board, int n) {// 打印出一个二维矩阵List<String> list=new ArrayList<>();for (int row = 0; row < n; ++row) { StringBuffer str = new StringBuffer();for (int column = 0; column < n; ++column) { if (board[row][column] == 1){str.append("Q");}else{str.append(".");} }list.add(str.toString());} return list;}
}

【总结】

1.回溯模板
List<> res = new LinkedList<>();
Deque<Integer> path =  new ArrayDeque<>();void dfs(路径, 选择列表){if 满足结束条件{res.add(路径);return;}for 选择 in 选择列表{// 做选择;// 标记一下已经选了,有些题目不需要标记nums[i] = true;// 把选择的放进路径path.push(i)dfs(路径, 选择列表);// 恢复现场;path.pop();nums[i] = false;}
}
2.回溯思想

【数据结构与算法】【算法思想】回溯算法

转载链接:https://leetcode-cn.com/problems/n-queens/solution/gen-ju-di-46-ti-quan-pai-lie-de-hui-su-suan-fa-si-/
转载链接:https://leetcode-cn.com/problems/n-queens/solution/java-hui-su-xiang-xi-zhu-jie-bu-tong-fang-fa-pan-d/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/424774.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编码解码错误

python读取文件时提示UnicodeDecodeError错误&#xff1a; "UnicodeDecodeError: gbk codec cant decode byte 0x80 in position 205: illegal multibyte sequence" “UnicodeDecodeError: cp950 codes cant decode byte oxc3 in position 25402: illegal multibyte …

java面试题2 牛客:定义类中成员变量时不可能用到的修饰是

懵逼树上懵逼果&#xff0c;懵逼树下你和我 第二题 定义类中成员变量时不可能用到的修饰是&#xff08;&#xff09; A final B void C protected D static 一看到这道题&#xff0c;有点慌了&#xff0c;直接选c&#xff0c;很显然&#xff0c;我又错了&#xff0c;难题…

[Leetcode][第257题][JAVA][二叉树的所有路径][BFS][DFS]

【问题描述】[简单] 【解答思路】 1. DFS 时间复杂度&#xff1a;O(N^2) 空间复杂度&#xff1a;O(N^2) class Solution {public List<String> binaryTreePaths(TreeNode root) {List<String> paths new ArrayList<String>();constructPaths(root, "…

Depth-first Search深度优先搜索专题1

104. Maximum Depth of Binary Tree 思路&#xff1a;顺着树的一个分支一直数层数直到叶子节点。DFS的思路。这个题目可以练习的是递归转迭代。 代码 695. Max Area of Island 思路&#xff1a;遇到点i,j;如果grid[i][j]没有被访问过&#xff0c;并且等于1&#xff0c;那么…

作用域和数组

作用域 就是一对大括号{} 作用域的的特点在作用域内部声明的变量,只能在这个作用域使用 数组 array 一组类型相同的数(值)1.数组一旦定义好长度就不能改变了2.数组访问摸个数据的方式 数组以下标(index)的方式获取数据 数组的声明 定义10个学员的成绩/两只之间以,隔开…

java面试题3 牛客:下面有关jdbc statement的说法错误的是

下面有关jdbc statement的说法错误的是&#xff1f; A JDBC提供了Statement、PreparedStatement 和 CallableStatement三种方式来执行查询语句&#xff0c; 其中 Statement 用于通用查询&#xff0c; PreparedStatement 用于执行参数化查询&#xff0c;而 CallableStatement则…

Depth-first Search深度优先搜索专题2

199. Binary Tree Right Side View 思路&#xff1a;想要得到树的每一层最右侧元素值&#xff0c;用BFS最方便。先访问左节点再访问右节点&#xff0c;最后访问的一个值就是留下的值。 想要DFS的思路也可以。只是一定要访问所有节点。 代码 491 Increasing Subsequences …

[Leetcode][第60题][JAVA][第k个排列][回溯][DFS][剪枝]

【问题描述】[中等] 【解答思路】 1. 回溯搜索算法 剪枝 &#xff0c;直接来到叶子结点 时间复杂度&#xff1a;O(N^2) 空间复杂度&#xff1a;O(N) import java.util.Arrays;public class Solution {/*** 记录数字是否使用过*/private boolean[] used;/*** 阶乘数组*/priv…

java面试题4 牛客:运行下列代码,运行结果为

第四题&#xff1a;运行下列代码&#xff0c;运行结果为&#xff08;&#xff09; class A {public A() {System.out.println("class A");}{ System.out.println("Im A class"); }static { System.out.println("class A static"); }}public cla…

蓝桥杯-每日刷题-026

奖金提成 一、题目要求 题目描述 企业发放的奖金根据利润提成。 利润I低于100000元的奖金可提10%&#xff1b; 利润高于100000元&#xff0c;低于200000元的&#xff08;100000<I<200000&#xff09;时,低于100000元的部分按10%提成&#xff0c;高于100000元的部分&…

优秀技术人的管理陷阱

写在前面 几乎每一位做软件开发的技术人&#xff0c;都听过类似这样的话&#xff0c;“30 岁以后&#xff0c;身体比不过 20 几岁的年轻人&#xff0c;需要转型做管理了”。这句话理解起来是没有问题的。的确年龄越大身体就越比不过自己 20 多岁的时候&#xff0c;拼体力不够&a…

机器学习中的数学--数学知识复习

机器学习 机器学习三个部分&#xff1a;编程能力数学统计知识业务知识 机器学习分类 1 监督学习&#xff1a;例如分类、房价预测 2 无监督学习&#xff1a;例如聚类 3 强化学习&#xff1a;例如动态系统、机器人控制系统 机器学习算法 是否连续无监督有监督连续聚类 &am…

【数据结构与算法】【算法思想】拓扑排序

一、拓扑排序 拓扑排序是基于依赖关系的节点&#xff0c;根据依赖关系而生成的序列。节点和依赖关系往往要生成有向无环图。类似的问题有&#xff1a;穿衣服裤子的先后关系&#xff0c;生成穿衣序列/专业课程与前置课程形成的课程学习序列/代码编译依赖关系形成的编译顺序序列…

java面试题5 牛客:下列关于JavaBean的说法正确的是:

下列关于JavaBean的说法正确的是&#xff1a; A:Java文件与Bean所定义的类名可以不同&#xff0c;但一定要注意区分字母的大小写 B:在JSP文件中引用Bean&#xff0c;其实就是用语句 C&#xff1a;被引用的Bean文件的文件名后缀为.java D:Bean文件放在任何目录下都可以被引用…

Depth-first Search深度优先搜索专题3

473. Matchsticks to Square 思路&#xff1a;有n根长度不一的火柴&#xff0c;这些火柴可以拼接在一起&#xff0c;但不能被折断。这些火柴能够围城一个正方形吗&#xff1f;每个火柴可以并且必须使用一次。分析得到每个边的长度应该是所有火柴长度和的1/4。接下来就是将火柴…

mysql数据库之事务与存储过程

事务 什么是事务&#xff1f; 事务是指一些SQL语句的集合&#xff0c;这些语句同时执行成功完成某项功能 事务的CAID特性&#xff1a; 原子性&#xff1a;一个事务的执行是整体性的&#xff0c;要么内部所有语句都执行成功&#xff0c;要么一个都别想成功 一致性&#xff1a;事…

java面试题6 牛客:哪个关键字可以对对象加互斥锁?

哪个关键字可以对对象加互斥锁&#xff1f;&#xff08;&#xff09; A synchronized B volatile C serialize D static synchronized的4种用法 1.方法声明时使用,放在范围操作符(public等)之后,返回类型声明(void等)之前.这时,线程获得的是成员锁,即一次只能有一个线程进…

[Leetcode][第347题][JAVA][前K个高频元素][优先队列][堆][遍历set/map]

【问题描述】[中等] 【解答思路】 1. 堆 复杂度 class Solution {public int[] topKFrequent(int[] nums, int k) {Map<Integer, Integer> occurrences new HashMap<Integer, Integer>();for (int num : nums) {occurrences.put(num, occurrences.getOrDefault…

Depth-first Search深度优先搜索专题4

576. Out of Boundary Paths 思路&#xff1a;这道题目难倒了我。最直接的思路是暴力搜索。要注意的问题1是需要仔细观察Example2&#xff0c;轨迹不同意思是可以从A点到B点&#xff0c;再从B点到A点也可以&#xff0c;只要step够用。所以暴力搜索&#xff0c;在(i,j)点在步骤…

java面试题7 牛客:关于AWT和Swing说法正确的是?

关于AWT和Swing说法正确的是&#xff1f; A Swing是AWT的子类 B AWT在不同操作系统中显示相同的风格 C AWT不支持事件类型&#xff0c;Swing支持事件模型 D Swing在不同的操作系统中显示相同的风格 AWT和Swing都是java中的包。 AWT(Abstract Window Toolkit)&#xff1a;…