DFS複習

1.括號生成

數字 n 代表生成括號的對數,請你設計一個函數,用於能夠生成所有可能的並且 有效的括號組合。

例如,給出 n = 3,生成結果爲:
[ "((()))", "(()())", "(())()", "()(())", "()()()" ]

思路:
有效括號的條件:每個左括號都有一個右括號與之匹配
(1)通過dfs每次插入一個括號,並記錄剩餘左右括號的個數
(2)當剩餘左括號比剩餘右括號多時,必然有左括號在後面插入後無法匹配,直接返回
(3)左右括號個數都使用完時,將字符串存入數組。

var generateParenthesis = function (n) {
    let ans = [];
    const dfs = (left, right, str) => {
        if (left > right) return;/* 左邊有無法匹配的 */
        if (!left && !right) {
            ans.push(str);
            return;
        }
        if (left) dfs(left - 1, right, str + '(');
        if (right) dfs(left, right - 1, str + ')');
    }
    dfs(n, n, '');
    return ans;
};

2.N皇后問題

n 皇后問題研究的是如何將 n 個皇后放置在 n×n 的棋盤上,並且使皇后彼此之間不能相互攻擊。
給定一個整數 n,返回所有不同的 n 皇后問題的解決方案。
n皇后

輸入: 4
輸出: [
 [".Q..",  // 解法 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // 解法 2
  "Q...",
  "...Q",
  ".Q.."]
]
解釋: 4 皇后問題存在兩個不同的解法。

思路:
放置皇后的座標需要具備的條件:
(1)不能和前面放置的皇后在同一列 y2!=y1
(2)不能和前面放置的皇后在同一對角線,|x2-x1|!=|y2-y1|
dfs按照層數選取放置位置(按照上述兩個條件判斷所便利的位置是否可以放置),用position存各層放置的座標,所有皇后已經放置完則將position記錄的聯繫轉化到字符串,存入數組即可。

var solveNQueens = function (n) {
    let ans = [];
    var isValid = (x, y, position) => {
        /* 遍歷x前面已經放置的層數 */
        for (let prex = 0; prex < x; prex++) {
            if (position[prex] === y)/* y列已經放置過 */
                return false;
            /* 在對角線上 */
            if (Math.abs(x - prex) === Math.abs(y - position[prex]))
                return false;
        }
        return true;
    }
    var getString = position => {
        let res = [];
        for (let i = 0; i < n; i++) {
            res[i] = '';
            for (let j = 0; j < n; j++) {
                res[i] += position[i] === j ? 'Q' : '.';
            }
        }
        return res;
    }
    var dfs = (x, position) => {
        if (x == n) {/* 全部已經放置完 */
            ans.push(getString(position));
            return;
        }
        for (let y = 0; y < n; y++) {
            if (isValid(x, y, position)) {/* 判斷(x,y)是否能放 */
                position[x] = y;
                dfs(x + 1, position);
            }
        }
    }
    dfs(0, []);
};

3.復原ip地址

給定一個只包含數字的字符串,復原它並返回所有可能的 IP 地址格式。

輸入: "25525511135"
輸出: ["255.255.11.135", "255.255.111.35"]

步驟:
(1)dfs每次切割1-3個字符形成串tmp,將切割的字符串存入數組arr
切割字符串符合的條件:
a.一位且轉化爲數字是0 ->tmp==='0'
b.轉化爲數字大小在[1,256]範圍內不能有前導零->parseInt(tmp) > 0 && parseInt(tmp) < 256
(2)將剩餘字符串str.substr(i)和數組arr穿給下一層繼續選擇切割
(3)存滿4層,若此時str爲空,說明所有字符都已經按照上述條件存入數組,利用join將數組轉化爲字符串並在中間加入分隔符.,存到Set中
(4)將Set轉化爲數組返回

var restoreIpAddresses = function (s) {
    let ans = new Set();
    const dfs = (str, arr, level) => {
        if (level == 4) {
            if (!str)
                ans.add(arr.join('.'));
            return;
        }
        for (let i = 1; i <= Math.min(str.length, 3); i++) {
            let tmp = str.substr(0, i);//切割前i個
            if (tmp === '0' || tmp.charAt(0) != 0 && parseInt(tmp) > 0 && parseInt(tmp) < 256) {
                arr[level] = tmp;
                dfs(str.substr(i), arr, level + 1);/* str切割i個傳給下一層 */
            }
        }
    }
    dfs(s, [], 0);
    return [...ans];
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章