DFS&BFS 套路
dfs
--- 初始化
checklist
答案
--- dfs入口
--- dfs函数
答案更新
终止条件
限制条件
递归dfs函数
--- 返回答案
var canVisitAllRooms2 = function (rooms) {
let len = rooms.length;
const checkList = Array(len).fill(0);
checkList[0] = 1;
function dfs(room) {
for (let key of room) {
if (checkList[key] === 0) {
checkList[key] = 1;
dfs(rooms[key]);
}
}
}
dfs(rooms[0]);
let ans = checkList.every((item) => item === 1);
return ans;
};
console.log(canVisitAllRooms2([[1, 3], [3, 0, 1], [2], [0]]));
bfs
- 通用 bfs
---- 初始化
checkList
queue
---- 首元素加入队列
---- 循环队列
while(queue.length)
取出队头shift
限制条件
往队列里加入新的元素
更新checkList
---- 返回答案
- 多源 bfs
---- 初始化
checkList
queue
level
---- 首批(多个)元素加入队列
---- 循环队列
while(queue.length)
for循环拿出第一批数据
取出队头shift
限制条件
往队列里加入新的元素
更新checkList
---- 返回答案
var orangesRotting = function (grid) {
let level = 0;
let freshNum = 0;
let x = grid.length;
let y = grid[0].length;
let queue = [];
let dir = [
[1, 0],
[-1, 0],
[0, 1],
[0, -1],
];
let checkList = Array(x)
.fill(0)
.map(() => Array(y).fill(0));
for (let i = 0; i < x; i++) {
for (let j = 0; j < y; j++) {
if (grid[i][j] === 2) {
queue.push([i, j]);
checkList[i][j] = 1;
} else if (grid[i][j] === 1) {
freshNum += 1;
}
}
}
if (freshNum === 0) return 0;
while (queue.length > 0) {
const len = queue.length;
level += 1;
for (let k = 0; k < len; k++) {
const [i, j] = queue.shift();
for (let d = 0; d < dir.length; d++) {
let nextI = i + dir[d][0];
let nextJ = j + dir[d][1];
if (
nextI >= 0 &&
nextI < x &&
nextJ >= 0 &&
nextJ < y &&
checkList[nextI][nextJ] === 0 &&
grid[nextI][nextJ] === 1
) {
queue.push([nextI, nextJ]);
checkList[nextI][nextJ] = 1;
freshNum -= 1;
}
}
}
}
if (freshNum > 0) return -1;
return level - 1;
};
console.log(
orangesRotting([
[2, 1, 1],
[1, 1, 0],
[0, 1, 1],
])
);
- 拓扑排序 bfs
---- 初始化
入度表
邻接表
队列
---- 根据入度表 初始化队列元素
---- 循环队列
拿出元素
根据邻接表获取对应值
入度表--
入度表为0加入队列
计算答案
---- 返回答案
const getTaskOrder = (tasks) => {
const len = tasks.length;
const grid = tasks.map((item) => item.split("->"));
console.log("grid", grid);
let taskList = [];
const intDegree = {};
let ans = "";
const map = {};
for (let i = 0; i < len; i++) {
let cur = grid[i][1];
let next = grid[i][0];
intDegree[next] === undefined
? (intDegree[next] = 1)
: (intDegree[next] += 1);
intDegree[cur] === undefined ? (intDegree[cur] = 0) : "";
map[cur] === undefined ? (map[cur] = [next]) : map[cur].push(next);
}
console.log(intDegree);
console.log(map);
let queue = [];
Object.keys(intDegree).forEach((key) => {
if (intDegree[key] === 0) {
queue.push(key);
taskList.push(key);
}
});
ans = taskList.sort().join(" ");
taskList = [];
while (queue.length) {
let cur = queue.shift();
let next = map[cur];
if (next && next.length) {
for (let i = 0; i < next.length; i++) {
let val = next[i];
intDegree[val]--;
if (intDegree[val] === 0) {
queue.push(val);
taskList.push(val);
}
}
}
}
return ans + " " + taskList.sort().join(" ");
};
console.log(getTaskOrder(["B->A", "C->A", "D->B", "D->C", "D->E"]));
- 启发 bfs
---- 不用队列了, 借用数组
---- 每走一步都选取最优值
---- while循环
满足条件退出
更新答案
const getPath = (r, c, grid) => {
let ans = Math.min(grid[0][0], grid[r - 1][c - 1]);
const checkList = Array(r)
.fill(0)
.map(() => Array(c).fill(0));
checkList[0][0] = 1;
let isContinueFind = true;
const dirs = [
[0, 1],
[0, -1],
[-1, 0],
[1, 0],
];
const arr = [[grid[0][0], 0, 0]];
while (isContinueFind) {
arr.sort((a, b) => a[0] - b[0]);
let [curVal, curX, curY] = arr.pop();
ans = Math.min(ans, curVal);
for (let dir of dirs) {
let [dx, dy] = dir;
let nextX = dx + curX;
let nextY = dy + curY;
if (
nextX >= 0 &&
nextX < r &&
nextY >= 0 &&
nextY < c &&
checkList[nextX][nextY] === 0
) {
if (nextX === r - 1 && nextY === c - 1) {
isContinueFind = false;
break;
}
checkList[nextX][nextY] = 1;
arr.push([grid[nextX][nextY], nextX, nextY]);
}
}
}
return ans;
};
console.log(
getPath(3, 3, [
[5, 4, 5],
[1, 2, 6],
[7, 4, 6],
])
);