332.重新安排行程
代码实现:
var findItinerary = function (tickets) {
let result = ['JFK'];
let map = {};
for (const ticket of tickets) {
const [from, to] = ticket;
if (!map[from]) {
map[from] = []
}
map[from].push(to)
}
for (const city in map) {
map[city].sort()
}
function backtracing () {
if (result.length === tickets.length + 1) {
return true;
}
if (!map[result[result.length - 1]] || !map[result[result.length - 1]].length) {
return false;
}
for (let i = 0; i < map[result[result.length - 1]].length; i++) {
let city = map[result[result.length - 1]][i]
map[result[result.length - 1]].splice(i, 1);
result.push(city);
if (backtracing()) {
return true
}
result.pop();
map[result[result.length - 1]].splice(i, 0, city)
}
}
backtracing()
return result
};
51. N皇后
皇后们的约束条件:
- 不能同行
- 不能同列
- 不能同斜线
用皇后们的约束条件,来回溯搜索这棵树,只要搜索到了树的叶子节点,说明就找到了皇后们的合理位置了
代码实现:
function isValide (row, col, chessboard, n) {
for (let i = 0; i < row; i++) {
if (chessboard[i][col] === 'Q') {
return false
}
}
for (let i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
if (chessboard[i][j] === 'Q') {
return false
}
}
for (let i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
if (chessboard[i][j] === 'Q') {
return false
}
}
return true
}
function transformChessBoard (chessboard) {
let chessboardback = [];
chessboard.forEach(row => {
let rowStr = '';
row.forEach(value => {
rowStr += value;
})
chessboardback.push(rowStr)
})
return chessboardback;
}
var solveNQueens = function (n) {
let result = [];
const backtracing = (row, chessboard) => {
if (row === n) {
result.push(transformChessBoard(chessboard));
return;
}
for (let i = 0; i < n; i++) {
if (isValide(row, i, chessboard, n)) {
chessboard[row][i] = 'Q'
backtracing(row + 1, chessboard);
chessBoard[row][i] = '.'
}
}
}
let chessBoard = new Array(n).fill([]).map(() => new Array(n).fill('.'))
backtracing(0, chessBoard)
return result
};
37. 解数独
代码实现:
var solveSudoku = function (board) {
function isValide (row, col, val, board) {
let len = board.length
for (let i = 0; i < len; i++) {
if (board[row][i] === val) {
return false
}
}
for (let i = 0; i < len; i++) {
if (board[i][col] === val) {
return false
}
}
let startRow = Math.floor(row / 3) * 3
let 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] === val) {
return false
}
}
}
return true
}
function backtracing () {
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[0].length; j++) {
if (board[i][j] !== '.') continue
for (let val = 1; val <= 9; val++) {
if (isValide(i, j, `${val}`, board)) {
board[i][j] = `${val}`
if (backtracing()) {
return true;
}
board[i][j] = '.'
}
}
return false
}
}
return true;
}
backtracing(board)
return board
};
总结
回溯算法章节到此结束 总的来说 主要是配合递归使用 然后不同问题有不同的 对应方案,比如组合,排列等等 一系列问题,继续努力!