📜  深度优先搜索,一次选择一个变量的值,并在变量没有合法值可分配时返回 - TypeScript (1)

📅  最后修改于: 2023-12-03 15:11:06.782000             🧑  作者: Mango

深度优先搜索 - TypeScript

深度优先搜索(Depth-First Search,DFS)是一种常见的搜索算法,在求解有解状态的问题时有广泛应用。本文将详细介绍深度优先搜索算法在 TypeScript 中的实现。

算法思想

深度优先搜索算法是一种递归算法,其主要思想是在搜索过程中深入当前分支直到无路可走,然后返回上一层,尝试其他分支,直到找到最优解或者搜索完所有分支。

具体实现时,我们需要记录每个节点是否被访问过,一般使用一个数组来存储访问状态。在递归搜索过程中,我们对每个未被访问的节点进行访问,并递归搜索其相邻节点。如果当前节点的相邻节点都已被访问,则返回上一层,尝试其他相邻节点。如果搜索整个图后没有找到解,则返回找不到解的提示信息。

算法实现

下面是深度优先搜索算法在 TypeScript 中的实现:

function dfs(node: number, visited: boolean[], graph: number[][]) {
  visited[node] = true;
  console.log('访问节点:', node);
  for (let i = 0; i < graph[node].length; i++) {
    const nextNode = graph[node][i];
    if (!visited[nextNode]) {
      dfs(nextNode, visited, graph);
    }
  }
}

function depthFirstSearch(graph: number[][]) {
  const visited: boolean[] = new Array(graph.length).fill(false);
  for (let i = 0; i < graph.length; i++) {
    if (!visited[i]) {
      dfs(i, visited, graph);
    }
  }
}

这里我们以一个邻接表来表示图,其中 graph[i] 表示节点 i 的相邻节点列表。在 depthFirstSearch 函数中,我们遍历每个节点,对未被访问的节点进行深度优先搜索。

应用举例

下面是深度优先搜索算法在解数独问题上的应用举例:

function solveSudoku(board: string[][]) {
  function isValid(row: number, col: number, c: string): boolean {
    for (let i = 0; i < 9; i++) {
      if (board[i][col] === c) return false;
      if (board[row][i] === c) return false;
      const boxRow = Math.floor(row / 3) * 3 + Math.floor(i / 3);
      const boxCol = Math.floor(col / 3) * 3 + (i % 3);
      if (board[boxRow][boxCol] === c) return false;
    }
    return true;
  }

  function backtracking() {
    for (let row = 0; row < 9; row++) {
      for (let col = 0; col < 9; col++) {
        if (board[row][col] !== '.') continue;
        for (let c = '1'; c <= '9'; c++) {
          if (!isValid(row, col, c)) continue;
          board[row][col] = c;
          if (backtracking()) return true;
          board[row][col] = '.';
        }
        return false;
      }
    }
    return true;
  }

  backtracking();
}

这里我们用深度优先搜索算法来解数独,其中 board 是一个 9x9 的数组,存储数独数字。在 backtracking 函数中,我们遍历整个数独,对未填数字的格子依次填入合法的数字,并递归搜索下一个未填数字的格子。如果搜索到整个数独,说明已找到一组解,返回 true。如果在递归搜索过程中发现填入的数字导致出现矛盾,返回 false,回溯到上一个格子重新尝试填入其他数字。