成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

[Leetcode] N-Queens N皇后

YanceyOfficial / 1272人閱讀

摘要:暴力法復雜度時間空間思路因為皇后問題中,同一列不可能有兩個皇后,所以我們可以用一個一維數(shù)組來表示二維棋盤上皇后的位置。一維數(shù)組中每一個值的下標代表著對應棋盤的列,每一個值則是那一列中皇后所在的行。

N-Queens I

The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.

Given an integer n, return all distinct solutions to the n-queens puzzle.

Each solution contains a distinct board configuration of the n-queens" placement, where "Q" and "." both indicate a queen and an empty space respectively.

For example, There exist two distinct solutions to the 4-queens puzzle:

[
 [".Q..",  // Solution 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // Solution 2
  "Q...",
  "...Q",
  ".Q.."]
]
暴力法 復雜度

時間 O(N^3) 空間 O(N)

思路

因為n皇后問題中,同一列不可能有兩個皇后,所以我們可以用一個一維數(shù)組來表示二維棋盤上皇后的位置。一維數(shù)組中每一個值的下標代表著對應棋盤的列,每一個值則是那一列中皇后所在的行。這樣我們可以只對一個一維數(shù)組進行深度優(yōu)先搜索,來找出對于每一列,我們的皇后應該放在哪一行。在下一輪搜索之前,我們先檢查一下新構(gòu)成的數(shù)組是否是有效的,這樣可以剪掉不必要的分支。檢查的方法則是看之前排好的每一個皇后是否沖突。

代碼
public class Solution {
    
    List> res;
    
    public List> solveNQueens(int n) {
        res = new LinkedList>();
        int[] nqueens = new int[n];
        helper(nqueens, n, 0);
        return res;
    }
    
    public void helper(int[] nqueens, int n, int i){
        if(i == nqueens.length){
            List one = new LinkedList();
            // 構(gòu)成表示整個棋盤的字符串
            for(int num : nqueens){
                // 構(gòu)成一個形如....Q....的字符串
                StringBuilder sb = new StringBuilder();
                for(int j = 0; j < num; j++){
                    sb.append(".");
                }
                sb.append("Q");
                for(int j = num + 1; j < n; j++){
                    sb.append(".");
                }
                one.add(sb.toString());
            }
            res.add(one);
        } else {
            //選擇下一列的數(shù)字
            // 比如之前已經(jīng)選了13xxxxxx,下一列可以選6,形成136xxxxx
            for(int num = 0; num < n; num++){
                nqueens[i] = num;
                // 如果是有效的,繼續(xù)搜索
                if(isValid(nqueens, i)){
                    helper(nqueens, n, i+1);
                }
            }
        }
    }
    
    private boolean isValid(int[] nqueens, int i){
        for(int idx = 0; idx < i; idx++){
            // 檢查對角線只要判斷他們差的絕對值和坐標的差是否相等就行了
            if(nqueens[idx] == nqueens[i] || Math.abs(nqueens[idx] - nqueens[i]) ==  i - idx){
                return false;
            }
        }
        return true;
    }
}
集合法 復雜度

時間 O(N^2) 空間 O(N)

思路

該方法的思路和暴力法一樣,區(qū)別在于,之前我們判斷一個皇后是否沖突,是遍歷一遍當前皇后排列的列表,看每一個皇后是否沖突。這里,我們用三個集合來保存之前皇后的信息,就可以O(shè)(1)時間判斷出皇后是否沖突。三個集合分別是行集合,用于存放有哪些行被占了,主對角線集合,用于存放哪個右上到左下的對角線被占了,副對角線集合,用于存放哪個左上到右下的對角線被占了。如何唯一的判斷某個點所在的主對角線和副對角線呢?我們發(fā)現(xiàn),兩個點的行號加列號的和相同,則兩個點在同一條主對角線上。兩個點的行號減列號的差相同,則兩個點再同一條副對角線上。

注意

主對角線row + col,副對角線row - col

代碼
public class Solution {
    
    List> res = new LinkedList>();;
    Set rowSet = new HashSet();
    Set diag1Set = new HashSet();
    Set diag2Set = new HashSet();
    
    public List> solveNQueens(int n) {
        helper(new LinkedList(), n, 0);
        return res;
    }
    
    public void helper(LinkedList tmp, int n, int col){
        if(col == n){
            List one = new LinkedList();
            for(Integer num : tmp){
                StringBuilder sb = new StringBuilder();
                for(int j = 0; j < num; j++){
                    sb.append(".");
                }
                sb.append("Q");
                for(int j = num + 1; j < n; j++){
                    sb.append(".");
                }
                one.add(sb.toString());
            }
            res.add(one);
        } else {
            // 對于列col,看皇后應該放在第幾行
            for(int row = 0; row < n; row++){
                int diag1 = row + col;
                int diag2 = row - col;
                // 如果三條線上已經(jīng)有占據(jù)的皇后了,則跳過該種擺法
                if(rowSet.contains(row) || diag1Set.contains(diag1) || diag2Set.contains(diag2)){
                    continue;
                }
                // 用回溯法遞歸求解
                tmp.add(row);
                rowSet.add(row);
                diag1Set.add(diag1);
                diag2Set.add(diag2);
                helper(tmp, n, col + 1);
                diag2Set.remove(diag2);
                diag1Set.remove(diag1);
                rowSet.remove(row);
                tmp.removeLast();
            }
        }
    }
}
N-Queens II

Follow up for N-Queens problem.

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

暴力法 復雜度

時間 O(N^3) 空間 O(N)

思路

跟I的解法一樣,只不過把原本構(gòu)造字符串的地方換成了計數(shù)器加一。

代碼
public class Solution {
    
    List> res;
    int cnt = 0;
    
    public int totalNQueens(int n) {
        int[] nqueens = new int[n];
        helper(nqueens, n, 0);
        return cnt;
    }
    
    public void helper(int[] nqueens, int n, int i){
        if(i == nqueens.length){
            cnt++;
        } else {
            for(int num = 0; num < n; num++){
                nqueens[i] = num;
                if(isValid(nqueens, i)){
                    helper(nqueens, n, i+1);
                }
            }
        }
    }
    
    private boolean isValid(int[] nqueens, int i){
        for(int idx = 0; idx < i; idx++){
            if(nqueens[idx] == nqueens[i] || Math.abs(nqueens[idx] - nqueens[i]) ==  i - idx){
                return false;
            }
        }
        return true;
    }
}
集合法 復雜度

時間 O(N^2) 空間 O(N)

思路

跟I的解法一樣,只不過把原本構(gòu)造字符串的地方換成了計數(shù)器加一。

代碼
public class Solution {
    
    Set rowSet = new HashSet();
    Set diag1Set = new HashSet();
    Set diag2Set = new HashSet();
    int cnt = 0;
    
    public int totalNQueens(int n) {
        helper(n, 0);
        return cnt;
    }
    
    public void helper(int n, int col){
        if(col == n){
            cnt++;
        } else {
            for(int row = 0; row < n; row++){
                int diag1 = row + col;
                int diag2 = row - col;
                if(rowSet.contains(row) || diag1Set.contains(diag1) || diag2Set.contains(diag2)){
                    continue;
                }
                rowSet.add(row);
                diag1Set.add(diag1);
                diag2Set.add(diag2);
                helper(n, col + 1);
                diag2Set.remove(diag2);
                diag1Set.remove(diag1);
                rowSet.remove(row);
            }
        }
    }
}

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/64535.html

相關(guān)文章

  • leetcode51. N-Queens 【更新 加上leetcode52 N-Queens II

    摘要:題目要求這里的王后相當于國際圍棋的王后,該王后一共有三種移動方式水平垂直,對角線。并將當前的臨時結(jié)果作為下一輪的輸入進行下一輪的預判。這里我們進行了進一步的優(yōu)化,將轉(zhuǎn)化為,其中數(shù)組用來記錄該列是否被占領(lǐng),數(shù)組用來記錄該行占領(lǐng)了那一列。 題目要求 The n-queens puzzle is the problem of placing n queens on an n×n chessb...

    BingqiChen 評論0 收藏0
  • [LeetCode] 52. N-Queens II

    Problem The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other. showImg(https://segmentfault.com/img/bVQrOx?w=258&h=276); Given an intege...

    Binguner 評論0 收藏0
  • 6-9月技術(shù)文章匯總

    摘要:分布式的管理和當我在談論架構(gòu)時我在談啥狀態(tài)碼詳解無狀態(tài)協(xié)議和請求支持哪些方法分層協(xié)議棧有哪些數(shù)據(jù)結(jié)構(gòu)運用場景說說你常用的命令為什么要有包裝類面向?qū)ο蟮奶卣魇巧妒巧队惺裁春锰幭到y(tǒng)設(shè)計工程在線診斷系統(tǒng)設(shè)計與實現(xiàn)索引背后的數(shù)據(jù)結(jié)構(gòu)及算法原理軟技能 HTTP 【HTTP】分布式session的管理 【HTTP】Cookie和Session 【HTTP】當我在談論RestFul架構(gòu)時我在談啥?...

    miya 評論0 收藏0
  • 數(shù)據(jù)結(jié)構(gòu)與算法之精講「遞歸系列」

    摘要:終止條件遞推公式遞歸的分類通過做大量的題,根據(jù)遞歸解決不同的問題,引申出來的幾種解決和思考的方式。我們通過層與層之間的計算關(guān)系用遞推公式表達出來做計算,經(jīng)過層層的遞歸,最終得到結(jié)果值。 showImg(https://segmentfault.com/img/remote/1460000019222330); 前言 幾個月之前就想寫這樣一篇文章分享給大家,由于自己有心而力不足,沒有把真...

    zhichangterry 評論0 收藏0
  • 皇后問題的JavaScript解法

    摘要:關(guān)于八皇后問題的解法,總覺得是需要學習一下算法的,哪天要用到的時候發(fā)現(xiàn)真不會就尷尬了背景八皇后問題是一個以國際象棋為背景的問題如何能夠在的國際象棋棋盤上放置八個皇后,使得任何一個皇后都無法直接吃掉其他的皇后為了達到此目的,任兩個皇后都不能處 關(guān)于八皇后問題的 JavaScript 解法,總覺得是需要學習一下算法的,哪天要用到的時候發(fā)現(xiàn)真不會就尷尬了 背景 八皇后問題是一個以國際象棋為背...

    derek_334892 評論0 收藏0

發(fā)表評論

0條評論

YanceyOfficial

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<