代码随想录 Day30 - 回溯(六)
 作者:jjn0703
- 2023-07-29  江苏
 本文字数:1972 字
阅读完需:约 6 分钟
回溯章节总结
回溯是一种暴力搜索算法,适合解决的问题有:
组合问题
切割问题
子集问题
排列问题
棋盘问题
回溯可以抽象为一棵树形结构,横向为 for 循环控制宽度,纵向为递归控制的深度。
回溯算法实现一般需要一个叫 backtracking 的函数,其参数可以由自己在实现的过程中完善。函数内部需要先写一下递归的结束条件,且写一下结构收集的逻辑。
void backtracking(...参数) {  if(满足终止条件) {    收集结果;    return;  }  for(集合元素 in 可选项) {    处理节点;    backtraing(...下一阶段参数);    撤销选择;  }}复制代码
 作业题
51. N 皇后
package jjn.carl.backtrack;
import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.Scanner;
/** * @author Jjn * @since 2023/7/29 16:28 */public class LeetCode51 {    public List<List<String>> solveNQueens(int n) {        List<List<String>> result = new ArrayList<>();        char[][] board = new char[n][n];        for (char[] c : board) {            Arrays.fill(c, '.');        }        backtrack(n, result, 0, board);        return result;    }        private void backtrack(int n, List<List<String>> result, int row, char[][] board) {        if (row == n) {            List<String> snapshot = new ArrayList<>();            for (int i = 0; i < n; i++) {                snapshot.add(new String(board[i]));            }            result.add(snapshot);            return;        }        for (int column = 0; column < n; column++) {            if (isOkay(board, row, column, n)) {                board[row][column] = 'Q';                backtrack(n, result, row + 1, board);                board[row][column] = '.';            }        }    }        private boolean isOkay(char[][] board, int row, int column, int n) {        for (int i = 0; i < n; i++) {            if (board[i][column] == 'Q') {                return false;            }        }        for (int i = row - 1, j = column - 1; i >= 0 && j >= 0; i--, j--) {            if (board[i][j] == 'Q') {                return false;            }        }        for (int i = row - 1, j = column + 1; i >= 0 && j <= n - 1; i--, j++) {            if (board[i][j] == 'Q') {                return false;            }        }        return true;    }        public static void main(String[] args) {        Scanner scanner = new Scanner(System.in);        int i = scanner.nextInt();        List<List<String>> lists = new LeetCode51().solveNQueens(i);        System.out.println(String.join(",", lists.toString()));    }}
复制代码
 37. 解数独
class Solution {public void solveSudoku(char[][] board) {        backtrack(board);    }        private boolean backtrack(char[][] board) {        for (int i = 0; i < board.length; i++) {            for (int j = 0; j < board[0].length; j++) {                if (board[i][j] != '.') {                    continue;                }                for (char k = '1'; k <= '9'; k++) {                    if (isValid(i, j, k, board)) {                        board[i][j] = k;                        if (backtrack(board)) {                            return true;                        }                        board[i][j] = '.';                    }                }                return false;            }        }        return true;    }        private boolean isValid(int i, int j, int k, char[][] board) {        for (int l = 0; l < 9; l++) {            if (board[i][l] == k) {                return false;            }        }        for (int l = 0; l < 9; l++) {            if (board[l][j] == k) {                return false;            }        }        int startHeight = (i / 3) * 3;        int startWidth = (j / 3) * 3;        for (int row = startHeight; row < startHeight + 3; row++) {            for (int column = startWidth; column < startWidth + 3; column++) {                if (board[row][column] == k) {                    return false;                }            }        }        return true;    }}复制代码
 划线
评论
复制
发布于: 刚刚阅读数: 3
版权声明: 本文为 InfoQ 作者【jjn0703】的原创文章。
原文链接:【http://xie.infoq.cn/article/c0ed75f3b78b3241d315706f9】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
jjn0703
关注
Java工程师/终身学习者 2018-03-26 加入
USTC硕士/健身健美爱好者/Java工程师.










    
评论