• N-Queens II


    N-Queens II

    问题:

    Follow up for N-Queens problem.

    Now, instead outputting board configurations, return the total number of distinct solutions

    思路:

      典型的DFS方法+回溯,回溯在于不成功就清楚原先标记

    我的代码:

    public class Solution {
        public int totalNQueens(int n) {
            if(n <= 0)  return 0;
            char [][]board = new char[n+1][n+1];
            for(int i = 0; i <= n; i++)
            {
                for(int j = 0; j <= n; j++)
                {
                    board[i][j] = '.';
                }
            }
            testQueens(1,board, n);
            return num;
        }
        private int num = 0;
        public boolean testQueens(int curRow,char[][] board, int n)
        {
            if(curRow == n + 1) 
            {
                num ++;
                return true;
            }
            for(int y = 1; y <= n ; y++)
            {
                 if(canPut(board, curRow , y, n))
                 {
                    board[curRow][y] = 'Q';
                    if(!testQueens(curRow + 1, board, n))
                    {
                         board[curRow][y] = '.';
                    }
                 }
                
            }
            return false;
        }
        public boolean canPut(char [][]board, int x, int y, int n)
        {
            for(int row = 0; row <= x - 1; row++)
            {
                for(int col = 0; col <= n; col++)
                {
                    char c = board[row][col];
                    if(c == '.') continue;
                    else
                    {
                        if(y == col) return false;
                        if(col + row == y + x) return false;
                        if(col - row == y - x) return false;
                    }
                }
            }
            return true;
        }
    }
    View Code

    我的代码可修改之处:

    public void testQueens(int curRow,char[][] board, int n)
        {
            if(curRow == n + 1) 
            {
                num ++;
                return ;
            }
            for(int y = 1; y <= n ; y++)
            {
                 if(canPut(board, curRow , y, n))
                 {
                    board[curRow][y] = 'Q';
                    testQueens(curRow + 1, board, n);
                    board[curRow][y] = '.';
                 }
                
            }
            return ;
        }
    View Code

    他人代码:

    public class Solution {
        public static int sum;
        public int totalNQueens(int n) {
            sum = 0;
            int[] usedColumns = new int[n];
            placeQueen(usedColumns, 0);
            return sum;
        }
        public void placeQueen(int[] usedColumns, int row) {
            int n = usedColumns.length;
            
            if (row == n) {
                sum ++;
                return;
            }
            
            for (int i = 0; i < n; i++) {
                if (isValid(usedColumns, row, i)) {
                    usedColumns[row] = i;
                    placeQueen(usedColumns, row + 1);
                }
            }
        }
        public boolean isValid(int[] usedColumns, int row, int col) {
            for (int i = 0; i < row; i++) {
                if (usedColumns[i] == col) {
                    return false;
                }
                if ((row - i) == Math.abs(col-usedColumns[i])) {
                    return false;
                }
            }
            return true;
        }
    }
    View Code

    学习之处:

    • 显然命名之处 placeQueen 要比 testQueen更贴切 isValid 要比 canPut更加贴切一点
    • 我的代码里面 testQueens返回true代表一次成功的尝试,返回false代表这一次所有的情况的都尝试过了(尝试过程中有成功的也有失败的案例)
    • 由于testQueen 中true 和 false代表的事件非互斥,所以他人代码中干脆就没有进行判断true false 只有尝试一遍就可以了 故出现了我的代码可修改之处的代码
    • 他人的代码,只用一个数组记录测试了哪一列,更加简洁,越简洁,错误越少

    private int queenNum = 0;
    public int totalQueenNum(int n){
    if(n <= 0) return 0;
    int[][] queenMark = new int[n+1][n+1];
    for(int i=0; i<=n; i++){
    for(int j=0; j<=n; j++){
    queenMark[i][j] = 0;
    }
    }

    }
    void testQueue(int row, int[][] queenMark, int n){
    if(row == n+1){
    queenNum ++;
    return;
    }
    for(int col=1; col<=n; col++){
    if(isValid(queenMark, row, col,n)){
    queenMark[row][col] = 1;
    testQueue(row+1, queenMark, n);
    queenMark[row][col] = 0;
    }
    }
    }

    boolean isValid(int[][] queenMark, int x, int y, int n){
    for(int i=0; i<=x-1; i++){
    for(int j=0; j<=n; j++){
    if(queenMark[i][j] == 0) continue;
    if(j == y) return false;
    if((x+y) == (i+j)) return false;
    if((x-y) == (i-j)) return false;
    }
    }
    return true;
    }

  • 相关阅读:
    面试题目小结
    面试题目3
    C#中new和override区别
    [转]:存储过程与函数的区别
    [转载]:C# 面试题大全
    [转]:C++虚函数表解析
    【修订版】C#/ASP.Net 面试题及答案(1)
    [转载]:C# 中结构与类的区别
    [转载]:C#笔试题面试题锦集
    [转载]:SQL Server性能调优之执行计划深度剖析 第一节 浅析SQL执行的过程
  • 原文地址:https://www.cnblogs.com/sunshisonghit/p/4315147.html
Copyright © 2020-2023  润新知