Leetcode - N-Queens

My code:

import java.util.ArrayList;
import java.util.List;

public class Solution {
    public List<List<String>> solveNQueens(int n) {
        if (n <= 0)
            return null;
        ArrayList<List<String>> ret = new ArrayList<List<String>>();
        ArrayList<String> queens = new ArrayList<String>();
        boolean[][] isVisited = new boolean[n][n];
        helper(0, isVisited, ret, queens);
        return ret;
    }
    
    private boolean helper(int i, boolean[][] isVisited, 
            ArrayList<List<String>> ret, ArrayList<String> queens) {
        int row = isVisited.length;
        int col = isVisited.length;
        if (i >= row) {
            ret.add(new ArrayList<String>(queens));
            return true;
        }
        else {
            boolean isQueen = false;
            
            for (int k = 0; k < col; k++) {
                if (!isVisited[i][k]) {
                    boolean[][] isVisitedCurr = visit(i, k, isVisited);
                    String queen = formString(k, col);
                    queens.add(queen);
                    isQueen |= helper(i + 1, isVisitedCurr, ret, queens);
                    queens.remove(queens.size() - 1);
                }
            }
            return isQueen;
        }
    }
    
    private boolean[][] visit(int i, int j, boolean[][] isVisitedOld) {
        int row = isVisitedOld.length;
        int col = isVisitedOld.length;
        boolean[][] isVisited = new boolean[row][col];
        for (int m = 0; m < row; m++)
            for (int n = 0; n < col; n++)
                isVisited[m][n] = isVisitedOld[m][n];
        isVisited[i][j] = true;
        int left = j - 1;
        while (left >= 0)
            isVisited[i][left--] = true;
        int right = j + 1;
        while (right < col)
            isVisited[i][right++] = true;
        int up = i - 1;
        while (up >= 0)
            isVisited[up--][j] = true;
        int down = i + 1;
        while (down < row)
            isVisited[down++][j] = true;
        int leftUp = 1;
        while (i - leftUp >= 0 && j - leftUp >= 0) {
            isVisited[i - leftUp][j - leftUp] = true;
            leftUp++;
        }
        int rightUp = 1;
        while (i - rightUp >= 0 && j + rightUp < col) {
            isVisited[i - rightUp][j + rightUp] = true;
            rightUp++;
        }
        int leftDown = 1;
        while (i + leftDown < row && j - leftDown >= 0) {
            isVisited[i + leftDown][j - leftDown] = true;
            leftDown++;
        }
        int rightDown = 1;
        while (i + rightDown < row && j + rightDown < col) {
            isVisited[i + rightDown][j + rightDown] = true;
            rightDown++;
        }
        return isVisited;
    }
    
    private String formString(int k, int col) {
        String queen = "";
        for (int i = 0; i < k; i++)
            queen += ".";
        queen += "Q";
        for (int i = k + 1; i < col; i++)
            queen += ".";
        return queen;
    }
    
    public static void main(String[] args) {
        Solution test = new Solution();
        System.out.println(test.solveNQueens(2));
    }
}

基本一遍過了N皇后。贪惹。苏章。
感覺自己強暴了。。枫绅。泉孩。
爆炸了。撑瞧。棵譬。
感覺這道題目的思想還是DFS,permutation 那一類題目预伺,只不過形式夸張了一些订咸。
就如同那道面試題,求質(zhì)數(shù)的次方和酬诀。脏嚷。。都是換個形式瞒御。
所以這種需要你求出多種變化父叙,多種結(jié)果,然后存在一個容器里面的肴裙,一般都是這個思路趾唱。
具體思路我也不想說了。我想我不會忘記蜻懦。

**
總結(jié): permutation, dfs
**

Anyway, Good luck, Richardo!

My code:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Solution {
    public List<List<String>> solveNQueens(int n) {
        List<List<String>> ret = new ArrayList<List<String>>();
        if (n <= 0) {
            return ret;
        }
        
        helper(0, new boolean[n], new boolean[2 * n], new boolean[2 * n], new String[n], n, ret);
        return ret;
    }
    
    private void helper(int row, boolean[] col, boolean[] l1, boolean[] l2, String[] board, int n, List<List<String>> ret) {
        if (row >= n) {
            List<String> group = new ArrayList<String>();
            for (String s : board) {
                group.add(s);
            }
            ret.add(group);
            return;
        }
        for (int i = 0; i < n; i++) {
            int index1 = row - i + n;
            int index2 = 2 * n - i - row - 1;
            if (!col[i] && !l1[index1] && !l2[index2]) {
                col[i] = true;
                l1[index1] = true;
                l2[index2] = true;
                char[] level = new char[n];
                Arrays.fill(level, '.');
                level[i] = 'Q';
                board[row] = String.valueOf(level);
                helper(row + 1, col, l1, l2, board, n, ret);
                col[i] = false;
                l1[index1] = false;
                l2[index2] = false;
            }
        }
    }
}

以前的做法甜癞,太復(fù)雜了,雖然思路沒怎么變宛乃。
網(wǎng)上看了答案悠咱,感覺是真的簡潔。
reference:
https://discuss.leetcode.com/topic/8592/comparably-concise-java-code

我一直在思考一個問題:
backtracking 的時候征炼,我給某個位置放個皇后析既,我得把用來記錄狀態(tài)的 isVisited[][] 相關(guān)區(qū)域全部設(shè)置成true
之后回到這一層,再把它恢復(fù)過來谆奥。但恢復(fù)過來是不可能的眼坏,因為你可能把別的皇后做成的true轉(zhuǎn)換成false
唯一的解決方法,就是每次dfs的時候酸些,都拷貝一份isVisited[][] 下去宰译,然后上來的時候就不用再恢復(fù)了。
但這個很花空間擂仍,花時間囤屹。

問題就在于熬甚,皇后占著一個位置逢渔,行列我都可以輕松地拿一維數(shù)組來mark,但是斜方向的兩條線乡括,我無法用數(shù)組來衡量肃廓。
其實是有的

仔細觀察智厌,對于斜率小于0的那條線。

i - j, 同一條線上的盲赊,永遠是定值铣鹏,不同線上的,值都不同哀蘑。
當(dāng)然诚卸, i - j 可能 < 0,所以, 為了可以用數(shù)組來表示绘迁,統(tǒng)一加上 n
于是合溺,數(shù)組中的index = i - j + n

斜率小于0的那條線
n - col - row - 1 是定值,為了讓他大于0
所以index = 2 * n - col - row - 1
這樣每次backtracking,下去的時候就把他們置成true,回來的時候缀台,很輕松地置成false棠赛。之后的問題就簡單了。就是簡單地一個backtracking

已經(jīng)見過好幾次利用一個數(shù)就能標(biāo)志一條線的例子了膛腐。
比如
Max point on a line
利用 (y2 - y1) / (x2 - x1) = (y3 - y1) / (x3 - x1)
和 最大公約數(shù)睛约,找出一條直線的代表數(shù)字

比如這道題目, n * n 里面哲身,表示一條對稱線的方法辩涝。

Anyway, Good luck, Richardo! -- 09/23/2016

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市律罢,隨后出現(xiàn)的幾起案子膀值,更是在濱河造成了極大的恐慌,老刑警劉巖误辑,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沧踏,死亡現(xiàn)場離奇詭異,居然都是意外死亡巾钉,警方通過查閱死者的電腦和手機翘狱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來砰苍,“玉大人潦匈,你說我怎么就攤上這事∽迹” “怎么了茬缩?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長吼旧。 經(jīng)常有香客問我凰锡,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任掂为,我火速辦了婚禮裕膀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘勇哗。我一直安慰自己昼扛,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布欲诺。 她就那樣靜靜地躺著抄谐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪扰法。 梳的紋絲不亂的頭發(fā)上斯稳,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機與錄音迹恐,去河邊找鬼挣惰。 笑死,一個胖子當(dāng)著我的面吹牛殴边,可吹牛的內(nèi)容都是我干的憎茂。 我是一名探鬼主播,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼锤岸,長吁一口氣:“原來是場噩夢啊……” “哼竖幔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起是偷,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤拳氢,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蛋铆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體馋评,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年刺啦,在試婚紗的時候發(fā)現(xiàn)自己被綠了留特。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡玛瘸,死狀恐怖蜕青,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情糊渊,我是刑警寧澤右核,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站渺绒,受9級特大地震影響贺喝,放射性物質(zhì)發(fā)生泄漏磷瘤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一搜变、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧针炉,春花似錦挠他、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至镰烧,卻和暖如春拢军,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背怔鳖。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工茉唉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人结执。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓度陆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親献幔。 傳聞我的和親對象是個殘疾皇子懂傀,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,728評論 2 351

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

  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問題, 分享了一些自己做題目的經(jīng)驗。 張土汪:刷leetcod...
    土汪閱讀 12,740評論 0 33
  • 如果面試碰到這么難的題..感覺可以掛電話了蜡感。 這題看到首先第一個可以確定的是這個肯定會用到DFS backtrac...
    98Future閱讀 219評論 0 0
  • My code: 就把 I 改了下蹬蚁,就交了。思路差不多郑兴。核心就是犀斋,那兩條對稱斜線,是可以各用一個數(shù)字來表示的情连。 A...
    Richardo92閱讀 272評論 0 0
  • 四十五 處置 未央殿 眾人斂衣行禮闪水,“嬪妾參見皇后娘娘,娘娘長樂安康蒙具∏蛴埽” 君后神色淡然,冷冷道禁筏,“起吧持钉。” “謝娘...
    君清兮閱讀 283評論 0 1
  • 直視花香 欲望 人們的呻吟如發(fā)情的貓 時間不聒噪 眼神里藏著懦弱 面部肌肉包庇我的惡 詩歌和筆在犯罪 我是斯德哥爾...
    力挺蘑叔閱讀 204評論 4 4