zoukankan      html  css  js  c++  java
  • 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];
    };
    
  • 相关阅读:
    无法为数据库 'tempdb' 中的对象分配空间,因为 'PRIMARY' 文件组已满
    数据库通用分页存储过程
    ef linq 中判断实体中是否包含某集合
    linq 动态判断
    bootstrap切换按钮点击后显示的颜色
    abp vue vscode 配置
    abp ef codefirst Value cannot be null. Parameter name: connectionString
    git diff 分支1 分支2 --stat命令没有将所有的不同显示出来
    区块链相关介绍
    需求分析工作流程
  • 原文地址:https://www.cnblogs.com/aeipyuan/p/12783495.html
Copyright © 2011-2022 走看看