数据结构刷题(二十三):47全排列II、51N皇后、37解数独
创始人
2024-06-01 12:21:30
0

1.全排列II

题目链接

思路:回溯之排列问题并且有数组排序+标记数组。 回溯三部曲同46. 全排列。

过程图:https://programmercarl.com/0047.%E5%85%A8%E6%8E%92%E5%88%97II.html#%E6%80%9D%E8%B7%AF

注意:本题的去重操作主要在树层上。就是说同一树层上存在重复值时,需要进行去重,而且必然在第二层及以下层,同时需要使用标记数组对访问过的结点进行标记。

class Solution {List> res = new ArrayList<>();LinkedList path = new LinkedList<>();public List> permuteUnique(int[] nums) {// 标记数组boolean[] used = new boolean[nums.length];// 设置默认值为false 并对nums排序Arrays.fill(used, false);Arrays.sort(nums);back(nums,used);return res;}private void back(int[] nums, boolean[] used) {    // 终止条件if (nums.length == path.size()){res.add(new ArrayList<>(path));return;}for (int i = 0; i < nums.length; i++){// 当访问的结点已经访问过时直接continueif (used[i] == true)continue;// 当同一树层上存在重复值 used[i - 1] == false可以确保重复值仅访问一次if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false)continue;used[i] = true;path.add(nums[i]);back(nums, used);used[i] = false; // 回溯path.removeLast();}}
}

2.N皇后

题目链接

思路:回溯。

注意:1.皇后们的约束条件:不能同行,不能同列,不能同斜线

2.回溯三部曲

  • 递归函数参数:

n是棋盘的大小,然后用row来记录当前遍历到棋盘的第几层,还有棋盘本身chessboard

  • 递归终止条件:

只要搜索到了树的叶子节点,说明就找到了皇后们的合理位置了(边搜索边判断皇后的约束条件,若不符合约束条件,会直接跳出)。

  • 单层搜索的逻辑:

for循环用来横向遍历; 递归用来纵向遍历。具体逻辑见下图。

3.验证棋盘是否合法isValid函数:

isValid(row, i, n, chessboard:row是行, i是列,n是棋盘大小)

4.代码里的函数说明:

函数array2:是为了将每一行的字符数组(如果n=4,则每一行的字符数组就是4个元素)转换为一个字符串,然后将以字符串为单位生成list,添加到res中。(copyValueOf就是接受一个字符数组并返回一个字符串)

List> res = new ArrayList<>();public List> solveNQueens(int n) {// chessboard 用来记录棋盘元素char[][] chessboard = new char[n][n];// 默认都是'.'for (char[] c : chessboard) {Arrays.fill(c, '.');}// n是棋盘大小 row来记录当前遍历到棋盘的第几层back(n, 0, chessboard);return res;}//private void back(int n, int row, char[][] chessboard) {if (row == n){res.add(array2(chessboard));return;}for (int i = 0; i < n; i++){if (isValid(row, i, n, chessboard)){chessboard[row][i] = 'Q';back(n, row + 1, chessboard);chessboard[row][i] = '.'; // 回溯}}}// 判断是否符合皇后的约束条件  row是行,col是列,n是棋盘大小private boolean isValid(int row, int col, int n, char[][] chessboard) {// 检查列for (int i = 0; i < row; i++) {if (chessboard[i][col] == 'Q')return false;}// 检查45度角 (10点半方向)for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--){if (chessboard[i][j] == 'Q')return false;}// 检查135度角 (1点半方向)for (int i  = row - 1, j = col + 1; i>= 0 && j <= n - 1; i--, j++){if (chessboard[i][j] == 'Q')return false;}return true;}// 见注意public List array2(char[][] chessboard){List list = new ArrayList<>();for (char[] c : chessboard) {list.add(String.copyValueOf(c));}return list;}

3.解数独(难得很,希望面试抽不到)

题目链接

思路:判断棋盘是否合法有如下三个维度:

  • 同行是否重复

  • 同列是否重复

  • 9宫格里是否重复

回溯三部曲:

  • 递归函数以及参数:只要解数独找到一个符合的条件(就在树的叶子节点上)立刻就返回,所以用boolean,

  • 递归终止条件:单层逻辑判断中,针对每一行的判断,返回true和false就是终止条件

  • 单层逻辑:一个for循环遍历棋盘的行,一个for循环遍历棋盘的列,一行一列确定下来之后,递归遍历这个位置放9个数字的可能性!

class Solution {public void solveSudoku(char[][] board) {solveSudokuHelper(board);}private boolean solveSudokuHelper(char[][] board){//「一个for循环遍历棋盘的行,一个for循环遍历棋盘的列,// 一行一列确定下来之后,递归遍历这个位置放9个数字的可能性!」for (int i = 0; i < 9; i++){ // 遍历行for (int j = 0; j < 9; j++){ // 遍历列if (board[i][j] != '.'){ // 跳过原始数字continue;}for (char k = '1'; k <= '9'; k++){ // (i, j) 这个位置放k是否合适if (isValidSudoku(i, j, k, board)){board[i][j] = k;if (solveSudokuHelper(board)){ // 如果找到合适一组立刻返回return true;}board[i][j] = '.';}}// 9个数都试完了,都不行,那么就返回falsereturn false;// 因为如果一行一列确定下来了,这里尝试了9个数都不行,说明这个棋盘找不到解决数独问题的解!// 那么会直接返回, 「这也就是为什么没有终止条件也不会永远填不满棋盘而无限递归下去!」}}// 遍历完没有返回false,说明找到了合适棋盘位置了return true;}/*** 判断棋盘是否合法有如下三个维度:*     同行是否重复*     同列是否重复*     9宫格里是否重复*/private boolean isValidSudoku(int row, int col, char val, char[][] board){// 同行是否重复for (int i = 0; i < 9; i++){if (board[row][i] == val){return false;}}// 同列是否重复for (int j = 0; j < 9; j++){if (board[j][col] == val){return false;}}// 9宫格里是否重复int startRow = (row / 3) * 3;int startCol = (col / 3) * 3;for (int i = startRow; i < startRow + 3; i++){for (int j = startCol; j < startCol + 3; j++){if (board[i][j] == val){return false;}}}return true;}
}

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...