返回

LeetCode《初级算法》之有效的数独 -- JavaScript

前端

前言

LeetCode《初级算法》系列文章旨在为初级算法爱好者提供清晰易懂的算法解析和JavaScript代码实现。本篇我们来学习一道经典的算法题——有效的数独。数独是一种逻辑谜题,由一个9x9的网格组成,网格被细分为9个3x3的子网格。每个网格中包含数字1到9,每个数字只能出现一次。有效的数独要求每个子网格、每一行和每一列中都包含1到9的数字。

算法解析

暴力破解法

最简单的方法是暴力破解法,即对每个空格进行枚举,尝试所有可能的数字,直到找到一个有效的解。这种方法的时间复杂度是O(9^81),即使对于最快的计算机来说,也是非常耗时的。

回溯法

回溯法是一种更有效的方法,它通过递归的方式来解决问题。首先,我们从第一个空格开始,尝试所有可能的数字,如果找到一个有效的解,则继续尝试下一个空格;如果找不到有效的解,则回溯到上一个空格,尝试下一个数字。这种方法的时间复杂度是O(9^n),其中n是空格的数量。对于有效的数独问题,n最多为81,因此回溯法的最坏时间复杂度是O(9^81)。

Dancing Links 算法

Dancing Links算法是一种更高效的算法,它通过将数独问题转换为一个精确覆盖问题来解决。精确覆盖问题是指找到一个集合的子集,使得子集中的元素恰好覆盖集合中的所有元素。Dancing Links算法通过将数独问题中的数字转换为列,将行和列转换为行和列头来构建一个精确覆盖矩阵。然后,算法使用Dancing Links算法来找到一个精确覆盖解,该解对应于一个有效的数独解。Dancing Links算法的时间复杂度是O(n^3),其中n是网格的大小。

JavaScript 代码实现

/**
 * 检查数独是否有效
 *
 * @param {number[][]} board 9x9的数独网格
 * @return {boolean} 数独是否有效
 */
const isValidSudoku = (board) => {
  // 检查行
  for (let i = 0; i < 9; i++) {
    const row = board[i];
    if (!isValidSet(row)) {
      return false;
    }
  }

  // 检查列
  for (let j = 0; j < 9; j++) {
    const column = [];
    for (let i = 0; i < 9; i++) {
      column.push(board[i][j]);
    }
    if (!isValidSet(column)) {
      return false;
    }
  }

  // 检查子网格
  for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
      const subgrid = [];
      for (let k = 0; k < 3; k++) {
        for (let l = 0; l < 3; l++) {
          subgrid.push(board[i * 3 + k][j * 3 + l]);
        }
      }
      if (!isValidSet(subgrid)) {
        return false;
      }
    }
  }

  return true;
};

/**
 * 检查一个集合是否有效
 *
 * @param {number[]} set 集合
 * @return {boolean} 集合是否有效
 */
const isValidSet = (set) => {
  const numbers = new Set();
  for (const number of set) {
    if (number === 0) {
      continue;
    }
    if (numbers.has(number)) {
      return false;
    }
    numbers.add(number);
  }
  return true;
};

结语

通过本篇文章,我们学习了如何使用JavaScript来解决LeetCode《初级算法》系列中的《数组之有效的数独》问题。我们介绍了暴力破解法、回溯法和Dancing Links算法三种解决方法,并给出了JavaScript代码实现。希望这篇文章能帮助读者更好地理解和掌握数组相关算法的应用,也希望读者能够通过LeetCode《初级算法》系列文章提高自己的算法能力。