深度优先遍历 (DFS)和广度优先遍历(BFS)
- 对于问题求解树,深度优先遍历总是从根节点出发,优先遍历子节点,向上回溯到兄弟节点再递归,比如树的前、中、后序遍历
- 广度优先遍历从根节点出发,优先遍历兄弟节点,然后层层遍历子节点,比如树的层序遍历
LeetCode肝题
-
- 二叉树的堂兄弟节点
let dfs = (root, target, fa) => {
if (!root) return -1
if (root.val == target) return 0
fa.fa = root
let l = dfs(root.left, target, fa)
if (l != -1) return l + 1
fa.fa = root
l = dfs(root.right, target, fa)
if (l != -1) return l + 1
return -1
}
var isCousins = function(root, x, y) {
let d1, d2, f1, f2, fa = {fa: null}
d1 = dfs(root, x, fa)
f1 = fa.fa
d2 = dfs(root, y, fa)
f2 = fa.fa
console.log(d1, d2)
return d1 == d2 && f1.val != f2.val
};
var isCousins = function(root, x, y) {
let d1, d2, f1, f2, q = [{node: root, deep: 0}]
while(q.length > 0) {
let cur = q.shift()
if (cur.node.val == x) {
d1 = cur.deep
f1 = cur.fa
}
if (cur.node.val == y) {
d2 = cur.deep
f2 = cur.fa
}
if (cur.node.left) q.push({node: cur.node.left, deep: cur.deep + 1, fa: cur.node})
if (cur.node.right) q.push({node: cur.node.right, deep: cur.deep + 1, fa: cur.node})
}
return d1 == d2 && f1.val != f2.val
};
-
- 01 矩阵
var updateMatrix = function(mat) {
let m = mat.length, n = mat[0].length, vis = [], dir = [[0,1],[1,0],[0,-1],[-1,0]], que = []
for(let i = 0; i < m; i++) {
vis.push([])
for(let j = 0; j < n; j++) {
if (mat[i][j] == 0) {
vis[i].push(0)
que.push({i: i, j: j, k: 0})
} else vis[i].push(-1)
}
}
while(que.length > 0) {
const cur = que.shift()
for(let k = 0; k < 4; k++) {
let x = cur.i + dir[k][0]
let y = cur.j + dir[k][1]
if (x < 0 || x >= m) continue
if (y < 0 || y >= n) continue
if (vis[x][y] != -1) continue
vis[x][y] = cur.k + 1
que.push({i: x, j: y, k: vis[x][y]})
}
}
return vis
};
-
- 二进制矩阵中的最短路径
var shortestPathBinaryMatrix = function(grid) {
if(grid[0][0] == 1) return -1
let n = grid.length, que = [], vis = [], dir = [[0, 1],[0, -1],[-1, 0],[1, 0],[1, 1],[-1, 1],[1, -1],[-1, -1]]
for(let i = 0; i < n; i++) {
vis.push(new Array(n).fill(0))
}
que.push({i: 0, j: 0, k: 1})
while(que.length > 0) {
const cur = que.shift()
if (cur.i == n - 1 && cur.j == n - 1) return cur.k
for(let k = 0; k < 8; k++) {
let x = cur.i + dir[k][0]
let y = cur.j + dir[k][1]
if (x < 0 || x >= n) continue
if (y < 0 || y >= n) continue
if (grid[x][y] == 1) continue
if (vis[x][y]) continue
vis[x][y] = 1
que.push({i: x, j: y, k: cur.k + 1})
}
}
return -1
};
-
- 打开转盘锁
function changeStr(str,index,changeStr){
return str.substr(0, index) + changeStr + str.substring(index + 1);
}
var getStr = function(str, i, j) {
if (j == 0) str = changeStr(str, i, parseInt(str[i]) == 9 ? 0 : parseInt(str[i]) + 1)
if (j == 1) str = changeStr(str, i, parseInt(str[i]) == 0 ? 9 : parseInt(str[i]) - 1)
return str
}
var openLock = function(deadends, target) {
let que = [], vis = {}
for(let item of deadends) {
vis[item] = 1
}
if (vis['0000']) return -1
que.push({s: '0000', k: 0})
while(que.length > 0) {
const cur = que.shift()
if (cur.s == target) return cur.k
for(let i = 0; i < 4; i++) {
for(let j = 0; j < 2; j++) {
let s = getStr(cur.s, i, j)
if (vis[s]) continue
vis[s] = 1
que.push({s, k: cur.k + 1})
}
}
}
return -1
};
- 剑指 Offer 13. 机器人的运动范围
function getSum(m) {
var a = 0;
while (m) {
a += m % 10;
m = parseInt(m / 10);
}
return a;
}
var movingCount = function(m, n, k) {
if (k == 0) return 1
let que = [], vis = [], dir = [[0, 1],[0, -1],[1, 0],[-1, 0],], cut = 0
for(let i = 0; i < m; i++) {
vis.push([])
for(let j = 0; j < n; j++) {
vis[i].push(0)
}
}
que.push({i: 0, j: 0})
while(que.length > 0) {
const cur = que.shift()
for(let i = 0; i < 4; i++) {
let x = cur.i + dir[i][0]
let y = cur.j + dir[i][1]
if (x < 0 || x >= m) continue
if (y < 0 || y >= n) continue
if (vis[x][y]) continue
if (getSum(x) + getSum(y) > k) continue
que.push({i: x, j: y})
vis[x][y] = 1
cut++
}
}
return cut
};
-
- 被围绕的区域
let m, n, dir = [[0, 1],[0, -1],[-1, 0],[1, 0]]
var dfs = function(i, j, board) {
board[i][j] = 'o'
for(let k = 0; k < 4; k++) {
let x = i + dir[k][0]
let y = j + dir[k][1]
if (x < 0 || x >= m) continue
if (y < 0 || y >= n) continue
if (board[x][y] != 'O') continue
dfs(x, y, board)
}
}
var solve = function(board) {
m = board.length, n = board[0].length
for(let i = 0; i < m; i++) {
if (board[i][0] == 'O') dfs(i, 0, board)
if (board[i][n - 1] == 'O') dfs(i, n - 1, board)
}
for(let i = 0; i < n; i++) {
if (board[0][i] == 'O') dfs(0, i, board)
if (board[m - 1][i] == 'O') dfs(m - 1, i, board)
}
for(let i = 0; i < m; i++) {
for(let j = 0; j < n; j++) {
if (board[i][j] == 'O') board[i][j] = 'X'
else if (board[i][j] == 'o') board[i][j] = 'O'
}
}
};
-
- 目标和
let dfs = function(i, target, nums) {
if (i == nums.length) {
if (target == 0) return 1
else return 0
}
let ans = 0
ans += dfs(i + 1, target - nums[i], nums)
ans += dfs(i + 1, target + nums[i], nums)
return ans
}
var findTargetSumWays = function(nums, target) {
return dfs(0, target, nums)
};
-
- 火柴拼正方形
let dfs = function(index, arr, ms) {
if (index == -1) return true
for(let i = 0; i < 4; i++) {
if (arr[i] < ms[index]) continue
if (arr[i] == ms[index] || arr[i] - ms[index] >= ms[0]) {
arr[i] -= ms[index]
if (dfs(index - 1, arr, ms)) return true
arr[i] += ms[index]
}
}
return false
}
var makesquare = function(matchsticks) {
let sum = 0
for(let item of matchsticks) sum += item
if (sum % 4) return false
matchsticks.sort((a, b) => a - b)
let arr = new Array(4).fill(sum / 4)
return dfs(matchsticks.length - 1, arr, matchsticks)
};
-
- 组合总和
var combinationSum = function(candidates, target) {
let ans = [], buff = []
var dfs = function(ind, target, nums) {
if (target < 0) return
if (target == 0) {
ans.push(JSON.parse(JSON.stringify(buff)))
return
}
if (ind == nums.length) return
dfs(ind + 1, target, nums)
buff.push(nums[ind])
dfs(ind, target - nums[ind], nums)
buff.pop()
}
dfs(0, target, candidates)
return ans
};
-
- N 皇后
var solveNQueens = function(n) {
let ans = [], buff = [], col = new Array(10).fill(0), left = new Array(20).fill(0), right = new Array(20).fill(0)
for(let i = 0; i < n; i++) {
buff.push([])
for(let j = 0; j < n; j++) {
buff[i].push('.')
}
}
let dfs = (i, n) => {
if (i == n) {
ans.push(buff.map(item => item.join('')))
}
for(let j = 0; j < n; j++) {
let l = i - j + 10, r = i + j
if (col[j] || left[l] || right[r]) continue
buff[i][j] = 'Q'
col[j] = 1
left[l] = 1
right[r] = 1
dfs(i + 1, n)
buff[i][j] = '.'
col[j] = 0
left[l] = 0
right[r] = 0
}
}
dfs(0, n)
return ans
};