代码随想录算法训练营Day30 | 332.重新安排行程,51. N皇后,37. 解数独

332.重新安排行程

题目链接/文章讲解

题目

给你一份航线列表 tickets ,其中 tickets[i] = [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。

所有这些机票都属于一个从 JFK(肯尼迪国际机场)出发的先生,所以该行程必须从 JFK 开始。如果存在多种有效的行程,请你按字典排序返回最小的行程组合。

例如,行程 ["JFK", "LGA"] 与 ["JFK", "LGB"] 相比就更小,排序更靠前。
假定所有机票至少存在一种合理的行程。且所有的机票 必须都用一次 且 只能用一次。

输入:tickets = [["MUC","LHR"],["JFK","MUC"],["SFO","SJC"],["LHR","SFO"]]
输出:["JFK","MUC","LHR","SFO","SJC"]

答案

/**
 * @param {string[][]} tickets
 * @return {string[]}
 */
var findItinerary = function(tickets) {
    const res = ['JFK'], map = {};
    for(const item of tickets) {
        const [from, to] = item;
        if (!map[from]) map[from] = [];
        map[from].push(to);
    }
    for(const city in map) {
        map[city].sort();
    }
    const backtracking = function() {
        if(res.length === tickets.length +1) return true;
        const lastCity = map[res[res.length -1]]
        if(!lastCity || !lastCity.length) return false;
        for(let i = 0; i < lastCity.length; i++) {
            let city = lastCity[i];
            map[res[res.length -1]].splice(i, 1);
            res.push(city);
            if (backtracking()) return true;
            res.pop();
            map[res[res.length -1]].splice(i, 0, city);
        }
    }
    backtracking();
    return res;
};

51. N皇后

题目链接/文章讲解
视频讲解

题目

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。

输入:n = 4
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释:如上图所示,4 皇后问题存在两个不同的解法。

答案

/**
 * @param {number} n
 * @return {string[][]}
 */
var solveNQueens = function(n) {
    const res = [], chess = new Array(n).fill([]).map(() => new Array(n).fill('.'));
    const isValid = function(row, col, chess, n) {
        // 检查列
        for(let i = 0; i < row; i++) {
            if(chess[i][col] === 'Q') return false;
        }
        for(let i=row-1, j=col+1; i>=0&&j<=n; i--,j++) {
            if(chess[i][j] === 'Q') return false;
        }
        for(let i=row-1, j=col-1; i>=0&&j>=0; i--,j--) {
            if(chess[i][j] === 'Q') return false;
        }
        return true;
    }
    const transfomer = function(arr) {
        const path = [];
        for(let item of arr) {
            let str = '';
            item.forEach(element => {
                str += element;
            });
            path.push(str);
        }
        return path;
    }
    const backtracking = function(row) {
        for(let col = 0; col < n; col++) {
            if(isValid(row, col, chess, n)) {
                chess[row][col] = 'Q';
                backtracking(row+1);
                chess[row][col] = '.';
            }
        }
    }
    backtracking(0);
    return res;
};

37. 解数独

题目链接/文章讲解
视频讲解

题目

编写一个程序,通过填充空格来解决数独问题。

数独的解法需 遵循如下规则:

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 '.' 表示。

答案

/**
 * @param {character[][]} board
 * @return {void} Do not return anything, modify board in-place instead.
 */
var solveSudoku = function(board) {
    const len = board.length;
    const isValid = function(row, col, num, board) {
        for (let i = 0; i < len; i++) {
            if (board[row][i] === num+'') return false;
        }
        for (let i = 0; i < len; i++) {
            if (board[i][col] === num+'') return false;
        }
        const startRow = Math.floor(row/3)*3, startCol = Math.floor(col/3)*3;
        for (let i = startRow; i<startRow+3; i++) {
            for(let j = startCol; j<startCol+3; j++) {
                if(board[i][j] === num+'') return false;
            }
        }
        return true;
    }
    const backtracking = function() {
        for(let row = 0; row < len; row++) {
            for(let col = 0; col < board[row].length; col++) {
                console.log('11')
                if(board[row][col] !== '.') continue;
                console.log('222')
                for(let num = 1; num <=9; num++) {
                    console.log(row, col, num, isValid(row, col, num, board))
                    if(isValid(row, col, num, board)) {
                        board[row][col] = num + '';
                        if(backtracking()) return true; // 有合适的
                        board[row][col] = '.'
                    }
                }
                return false; // 9个数字都不合适
            }   
        }
        return true; // 遍历所有的之后还没返回,说明找到合适的棋盘了
    }
    backtracking();
    return board;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值