51. N-Queens

這是一道很經(jīng)典的題目好唯,相信很多程序員都知道馍资。

其實(shí)解題的思路很簡(jiǎn)單筒主,就是在每行枚舉選擇每個(gè)位置,判斷選則的位置是否符合要求鸟蟹。如果符合要求乌妙,繼續(xù)在下一行按照這個(gè)方法進(jìn)行;如果不符合建钥,枚舉試驗(yàn)當(dāng)前行下一個(gè)位置藤韵,當(dāng)前行如果所有位置都有沖突,則返回上一行選擇上一行下一個(gè)合適的位置熊经。

其實(shí)就是典型的深度優(yōu)先搜索的思路泽艘。自己的解題思路,整個(gè)棋盤(pán)當(dāng)前擺放的情況通過(guò)一個(gè)二維數(shù)組int[][] chess表示镐依;判斷當(dāng)前選的位置是否合法匹涮,只需要判斷它之前的兩個(gè)斜線方向和直線方向是否已放置過(guò)皇后;用List<Integer>記錄每個(gè)方案槐壳,最后再轉(zhuǎn)為L(zhǎng)ist<List<String>>然低,可以避免搜索過(guò)程中處理字符串的復(fù)雜步驟。下面是代碼:

int n;
public List<List<String>> solveNQueens(int n) {
    List<List<String>> res = new ArrayList<>();
    if (n <= 0) {
        return res;
    }

    this.n = n;
    //只記錄每行存放的點(diǎn)
    List<List<Integer>> paths = new ArrayList<>();
    //用一個(gè)chess數(shù)組記錄當(dāng)前擺放的情況
    int[][] chess = new int[n][n];

    helper(0, new ArrayList<>(), paths, chess);

    return convert(paths);
}

public void helper(int row, List<Integer> path, List<List<Integer>> paths, int[][] chess) {
    if (row == n) {
        paths.add(new ArrayList<>(path));
        return;
    }

    for (int col = 0; col < n; col++) {
        if (!isValid(row, col, chess)) {
            continue;
        }
        chess[row][col] = 1;
        path.add(col);
        helper(row + 1, path, paths, chess);
        chess[row][col] = 0;
        path.remove(path.size() - 1);
    }
}

public boolean isValid(int row, int col, int[][] chess) {
    if (row < 0 || row >= chess.length || col < 0 || col >= chess.length || chess[row][col] == 1) {
        return false;
    }

    for (int i = row - 1; i >= 0; i--) {
        if (chess[i][col] == 1) {
            return false;
        }
    }

    for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
        if (chess[i][j] == 1) {
            return false;
        }
    }

    for (int i = row - 1, j = col + 1; i >= 0 && j < chess.length; i--, j++) {
        if (chess[i][j] == 1) {
            return false;
        }
    }

    return true;
}

public List<List<String>> convert(List<List<Integer>> resi) {
    List<List<String>> ress = new ArrayList<>();
    if (resi == null || resi.size() == 0) {
        return ress;
    }

    for (int i = 0; i < resi.size(); i++) {
        List<String> subres = new ArrayList<>();
        for (int j = 0; j < resi.get(i).size(); j++) {
            StringBuffer buffer = new StringBuffer();
            for (int k = 0; k < n; k++) {
                if (k == resi.get(i).get(j)) {
                    buffer.append('Q');
                } else {
                    buffer.append('.');
                }
            }
            subres.add(buffer.toString());
        }
        ress.add(subres);
    }

    return ress;
}

看了leetcode上discuss上的解法,有兩個(gè)部分處理的更優(yōu):
1雳攘、整個(gè)棋盤(pán)的狀態(tài)通過(guò)一個(gè)char[][]數(shù)組記錄带兜,這樣最后直接把char數(shù)組轉(zhuǎn)為L(zhǎng)ist<List<String>>即可,比自己的方法節(jié)省了一個(gè)paths的空間吨灭。
2刚照、判斷每個(gè)位置是否合法的函數(shù),巧妙的通過(guò)坐標(biāo)值的計(jì)算判斷喧兄。
第一個(gè)優(yōu)點(diǎn)體現(xiàn)的是選擇合適的數(shù)據(jù)結(jié)構(gòu)的能力无畔;第二個(gè)優(yōu)點(diǎn)體現(xiàn)的是對(duì)題目全面洞察并進(jìn)行條件轉(zhuǎn)換的能力。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末繁莹,一起剝皮案震驚了整個(gè)濱河市檩互,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌咨演,老刑警劉巖闸昨,帶你破解...
    沈念sama閱讀 212,080評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異薄风,居然都是意外死亡饵较,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)遭赂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)循诉,“玉大人,你說(shuō)我怎么就攤上這事撇他∏衙ǎ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,630評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵困肩,是天一觀的道長(zhǎng)划纽。 經(jīng)常有香客問(wèn)我,道長(zhǎng)锌畸,這世上最難降的妖魔是什么勇劣? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,554評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮潭枣,結(jié)果婚禮上比默,老公的妹妹穿的比我還像新娘。我一直安慰自己盆犁,他們只是感情好命咐,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,662評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著谐岁,像睡著了一般醋奠。 火紅的嫁衣襯著肌膚如雪瓮下。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,856評(píng)論 1 290
  • 那天钝域,我揣著相機(jī)與錄音,去河邊找鬼锭魔。 笑死例证,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的迷捧。 我是一名探鬼主播织咧,決...
    沈念sama閱讀 39,014評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼漠秋!你這毒婦竟也來(lái)了笙蒙?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,752評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤庆锦,失蹤者是張志新(化名)和其女友劉穎捅位,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體搂抒,經(jīng)...
    沈念sama閱讀 44,212評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡艇搀,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,541評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了求晶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片焰雕。...
    茶點(diǎn)故事閱讀 38,687評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖芳杏,靈堂內(nèi)的尸體忽然破棺而出矩屁,到底是詐尸還是另有隱情,我是刑警寧澤爵赵,帶...
    沈念sama閱讀 34,347評(píng)論 4 331
  • 正文 年R本政府宣布吝秕,位于F島的核電站,受9級(jí)特大地震影響亚再,放射性物質(zhì)發(fā)生泄漏郭膛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,973評(píng)論 3 315
  • 文/蒙蒙 一氛悬、第九天 我趴在偏房一處隱蔽的房頂上張望则剃。 院中可真熱鬧,春花似錦如捅、人聲如沸棍现。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,777評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)己肮。三九已至士袄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谎僻,已是汗流浹背娄柳。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,006評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留艘绍,地道東北人赤拒。 一個(gè)月前我還...
    沈念sama閱讀 46,406評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像诱鞠,于是被迫代替她去往敵國(guó)和親挎挖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,576評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • 原題 n皇后問(wèn)題是將n個(gè)皇后放置在n*n的棋盤(pán)上航夺,皇后彼此之間不能相互攻擊蕉朵。給定一個(gè)整數(shù)n,返回所有不同的n皇后問(wèn)...
    Jason_Yuan閱讀 2,080評(píng)論 0 0
  • 題目 The n-queens puzzle is the problem of placing n queens...
    Al73r閱讀 257評(píng)論 0 0
  • 不知道簡(jiǎn)書(shū)搞什么阳掐。始衅。剛才編輯了一下這個(gè)文章(原本是3.4寫(xiě)的),結(jié)果更新之后URL失效了锚烦,怎么也找不到了觅闽。。還好之...
    DrunkPian0閱讀 227評(píng)論 0 0
  • 這題是dfs套路涮俄,按照常理想的話我們需要一個(gè)存儲(chǔ)坐標(biāo)的數(shù)據(jù)結(jié)構(gòu)蛉拙,但這題只要一個(gè)一維數(shù)組就夠了,因?yàn)閚皇后的橫坐標(biāo)正...
    DrunkPian0閱讀 297評(píng)論 0 0
  • 題目 The n-queens puzzle is the problem of placing n queens...
    persistent100閱讀 358評(píng)論 0 0