LeetCode 51. N-Queens

Leetcode : N-Queens
Diffculty:Hard

N皇后問(wèn)題,對(duì)八皇后問(wèn)題的擴(kuò)展,典型的回溯法算法題。
具體八皇后問(wèn)題可以參考八皇后問(wèn)題詳解(四種解法)

LeetCode 這道題的擴(kuò)展在于,不只是擴(kuò)展到N皇后的情形,還要求把每一個(gè)結(jié)果都返回。

由于棋盤(pán)是對(duì)稱(chēng)的,那么我們只需要求第一個(gè)皇后為起點(diǎn),在棋盤(pán)左邊的結(jié)果,那么對(duì)于中軸線(xiàn)對(duì)稱(chēng)以后,一定有一個(gè)在右邊對(duì)稱(chēng)的結(jié)果。(此處要判斷N的奇偶性)
具體做法:
1)我們可以建立一個(gè)二維數(shù)組,0表示未占用,1表示占用。
2)然后以y軸逐層向下找可以放皇后的位置,每到一層,就把x從0~len 找一遍。
3)checkPosition方法,只需要找左上,上,和右上 即可。(因?yàn)槭菑纳贤抡椅恢玫?,下面的找到的一定是滿(mǎn)足上面已放置皇后的情況。)

下面上代碼:

// 4ms - beats 91.99%
// 這里一定要注意奇偶判斷,對(duì)于奇數(shù)情況,要對(duì)中間的那個(gè)位置在找一遍結(jié)果,并且image=false
public static List<List<String>> solveNQueens(int n) {
        List<List<String>> result = new ArrayList<>();
        int[][] cheese = new int[n][n];
        for(int i=0; i<n/2; i++){
            backtrack(cheese, result, 0, i, true);
        }
        if(n%2 == 1){
            backtrack(cheese, result, 0, n/2, false);
        }
        return result;
    }

// image 表示是否對(duì)找到的結(jié)果進(jìn)行鏡像翻轉(zhuǎn)。
private static void backtrack(int[][] cheese, List<List<String>> result, int y, int x, boolean image){
        cheese[y][x] = 1;
        if(y == cheese.length-1){
            addResult(cheese, result, image);
        }else{
            for(int i=0; i<cheese[0].length; i++){
                if(checkPosition(cheese, y+1, i)){
                    backtrack(cheese, result, y+1, i, image);
                }
            }
        }
        cheese[y][x] = 0;
    }


private static void addResult(int[][] cheese, List<List<String>> result, boolean image){
        List<String> list = new ArrayList<>(cheese.length);
        List<String> imageList = null;
        if(image){
            imageList = new ArrayList<>(cheese.length);
        }
        for(int i=0; i<cheese.length; i++){
            StringBuilder bu = new StringBuilder();
            for(int j=0; j<cheese[0].length; j++){
                if(cheese[i][j] == 1){
                    bu.append("Q");
                }else{
                    bu.append(".");
                }
            }
            list.add(bu.toString());
            if(image){
                imageList.add(bu.reverse().toString());
            }
        }
        result.add(list);
        if(image){
            result.add(imageList);
        }
    }

private static boolean checkPosition(int[][] cheese, int y, int x){
        int left=x, right=x;
        int len = cheese[0].length;
        boolean leftCheck, rightCheck, upCheck, result;
        for(int i=y-1; i>=0; i--){
            left -= 1;
            right +=1;
            leftCheck = left<0 ? true : cheese[i][left]==0;
            rightCheck = right>=len ? true : cheese[i][right]==0;
            upCheck = cheese[i][x]==0;
            result = leftCheck && rightCheck && upCheck;
            if(!result){
                return false;
            }
        }
        return true;
    }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容