DFS
电话号码的字母组合
ts
const digitLetters = [
'',
'',
'abc',
'def',
'ghi',
'jkl',
'mno',
'pqrs',
'tuv',
'wxyz',
];
function letterCombinations(digits: string): string[] {
if (!digits) {
return [];
}
const res: string[] = [];
const tokens: string[] = [];
const n = digits.length;
function dfs(index: number) {
if (index === n) {
res.push(tokens.join(''));
return;
}
const digit = +digits[index];
for (const letter of digitLetters[digit]) {
tokens.push(letter);
dfs(index + 1);
tokens.pop();
}
}
dfs(0);
return res;
}
括号生成
ts
function generateParenthesis(n: number): string[] {
const ans: string[] = [];
const tokens: string[] = [];
function dfs(leftRemain: number, rightRemain: number) {
if (tokens.length === n * 2) {
ans.push(tokens.join(''));
return;
}
if (leftRemain > 0) {
tokens.push('(');
dfs(leftRemain - 1, rightRemain);
tokens.pop();
}
if (leftRemain < rightRemain) {
tokens.push(')');
dfs(leftRemain, rightRemain - 1);
tokens.pop();
}
}
dfs(n, n);
return ans;
}
组合总和
ts
function combinationSum(candidates: number[], target: number): number[][] {
const res: number[][] = [];
candidates.sort((a, b) => a - b);
const nums: number[] = [];
function dfs(index: number, sum: number) {
if (sum >= target) {
if (sum === target) {
res.push(nums.slice());
}
return;
}
const n = candidates.length;
for (let i = index; i < n; ++i) {
if (i > 0 && candidates[i] === candidates[i - 1]) {
continue;
}
const candidate = candidates[i];
nums.push(candidate);
dfs(i, sum + candidate);
nums.pop();
}
}
dfs(0, 0);
return res;
}
全排列
js
function permute(nums) {
const n = nums.length;
const vis = new Array(n).fill(false);
const res = [];
const stack = [];
const dfs = () => {
if (stack.length === n) {
res.push(stack.slice());
return;
}
for (let i = 0; i < n; ++i) {
if (vis[i]) {
continue;
}
stack.push(nums[i]);
vis[i] = true;
dfs();
vis[i] = false;
stack.pop();
}
};
dfs();
return res;
}
全排列 II
js
function permuteUnique(nums) {
nums.sort((a, b) => a - b);
const n = nums.length;
const vis = new Array(n).fill(false);
const res = [];
const stack = [];
const dfs = () => {
if (stack.length === n) {
res.push(stack.slice());
return;
}
for (let i = 0; i < n; ++i) {
if (vis[i] || (i > 0 && nums[i] === nums[i - 1] && !vis[i - 1])) {
continue;
}
stack.push(nums[i]);
vis[i] = true;
dfs();
vis[i] = false;
stack.pop();
}
};
dfs();
return res;
}
子集
ts
function subsets(nums: number[]): number[][] {
const res: number[][] = [];
const seq: number[] = [];
const n = nums.length;
function dfs(index: number, total: number) {
if (seq.length === total) {
res.push(seq.slice());
return;
}
for (let i = index; i < n; ++i) {
seq.push(nums[i]);
dfs(i + 1, total);
seq.pop();
}
}
for (let len = 0; len <= n; ++len) {
dfs(0, len);
}
return res;
}
单词搜索
ts
function exist(board: string[][], word: string): boolean {
const m = board.length;
const n = board[0].length;
const vis = new Array(m).fill(0).map(() => new Array(n).fill(false));
function dfs(x: number, y: number, pos: number): boolean {
if (pos === word.length) {
return true;
}
if (x < 0 || x >= m || y < 0 || y >= n) {
return false;
}
if (vis[x][y] || board[x][y] !== word[pos]) {
return false;
}
vis[x][y] = true;
const steps = [
[-1, 0],
[0, -1],
[0, 1],
[1, 0],
];
for (const [dx, dy] of steps) {
if (dfs(x + dx, y + dy, pos + 1)) {
return true;
}
}
vis[x][y] = false;
return false;
}
for (let i = 0; i < m; ++i) {
for (let j = 0; j < n; ++j) {
if (dfs(i, j, 0)) {
return true;
}
}
}
return false;
}
岛屿数量
ts
function numIslands(grid: string[][]): number {
const m = grid.length;
const n = grid[0].length;
function dfs(x: number, y: number) {
if (x < 0 || x >= m || y < 0 || y >= n || grid[x][y] !== '1') {
return;
}
grid[x][y] = '0';
const steps = [
[-1, 0],
[1, 0],
[0, -1],
[0, 1],
];
for (const [dx, dy] of steps) {
dfs(x + dx, y + dy);
}
}
let res = 0;
for (let i = 0; i < m; ++i) {
for (let j = 0; j < n; ++j) {
if (grid[i][j] === '1') {
res += 1;
dfs(i, j);
}
}
}
return res;
}
除法求值
ts
function dfs(
graph: Map<string, [string, number][]>,
vis: Map<string, boolean>,
curr: string,
target: string
): number {
if (!graph.has(curr)) {
return -1.0;
}
if (curr === target) {
return 1.0;
}
if (vis.get(curr)) {
return -1.0;
}
vis.set(curr, true);
for (const [node, val] of graph.get(curr)) {
const res = dfs(graph, vis, node, target);
if (res !== -1.0) {
vis.set(curr, false);
return val * res;
}
}
vis.set(curr, false);
return -1.0;
}
function calcEquation(
equations: string[][],
values: number[],
queries: string[][]
): number[] {
const graph = new Map<string, [string, number][]>();
const vis = new Map<string, boolean>();
const n = equations.length;
for (let i = 0; i < n; ++i) {
const [a, b] = equations[i];
const val = values[i];
if (!graph.has(a)) {
graph.set(a, []);
}
graph.get(a).push([b, val]);
if (!graph.has(b)) {
graph.set(b, []);
}
graph.get(b).push([a, 1 / val]);
vis.set(a, false);
vis.set(b, false);
}
const res: number[] = [];
for (const [c, d] of queries) {
const quotient = dfs(graph, vis, c, d);
res.push(quotient);
}
return res;
}