一、几个简单的BFS问题
1、 层级遍历二叉树(leetcode#102)
var levelOrder = function(root) {
if(!root) return[]
const q = [root]
const res = []
while(q.length) {
const sz = q.length
const lev = []
for(let i = 0; i < sz; i++) {
const node = q.shift()
lev.push(node.val)
if(node.left) q.push(node.left)
if(node.right) q.push(node.right)
}
res.push(lev)
}
return res
};
2、二叉树的最小深度
var minDepth = function(root) {
if(!root) return 0
const q = [root]
let step = 1
while(q.length) {
const sz = q.length
for(let i = 0; i < sz; i++) {
const node = q.shift()
if(!node.left && !node.right) {
return step
}
if(node.left) q.push(node.left)
if(node.right) q.push(node.right)
}
step++
}
return step
};
实际上使用dfs也可以以相同的时间复杂度数量级O(N)解决这个问题
var minDepth = function(root) {
if(!root) return 0
if(root.left && !root.right) return minDepth(root.left)+1
if(!root.left && root.right) return minDepth(root.right)+1
return Math.min(minDepth(root.left)+1, minDepth(root.right)+1)
};
虽然都是O(N),但是BFS的平均时间肯定是比DFS小的,因为BFS在找到最短路径时就会停止。但是DFS的空间复杂度更低,使用递归栈来记录路径的方法最坏的时间复杂度也就是树的深度O(logN)。
二、开锁问题(leetcode#752)
简单介绍一下,一把锁四个槽位,每个位置可以滑动到从0-9,但是有一个deadends数组,碰到这里面的数字就会死亡,求不碰到deadends且拨到target的最小步数。
var plusOne = function(cur,idx) {
const listCode = cur.split('').map(num=>parseInt(num))
if(listCode[idx] === 9) {
listCode[idx] = 0
} else {
listCode[idx] += 1
}
return listCode.join('')
}
var minusOne = function(cur,idx) {
const listCode = cur.split('').map(num=>parseInt(num))
if(listCode[idx] === 0) {
listCode[idx] = 9
} else {
listCode[idx] -= 1
}
return listCode.join('')
}
var openLock = function(deadends, target) {
const q = ['0000']
let step = 0
const visited = new Set(deadends)
if(visited.has('0000')) return -1
while(q.length) {
const sz = q.length
for(let i = 0; i < sz; i++) {
const curCode = q.shift()
if(curCode === target) return step
// 对于每一个状态code,都有八个变化的方向, 将八个方向获得并推进队列
for(let j = 0; j < 4; j++){
const up = plusOne(curCode, j)
const down = minusOne(curCode, j)
if(!visited.has(up)){
q.push(up)
visited.add(up)
}
if(!visited.has(down)){
q.push(down)
visited.add(down)
}
}
}
step++
}
return -1
};
在这道题,我们使用一个hashmap来避免走回头路,同样deadends也是我们碰到就要抛弃的,所以deadends就可以作为hashmap的初始值。我们把开锁过程抽象成了一个图,在图的每个节点都有8种可能的方向(虽然有的方向可能是deadend),我们要找到从"0000"到target的最短距离。