【亡羊补牢】挑战数据结构与算法 第30期 LeetCode 37. 解数独(递归与回溯)

仰望星空的人,不应该被嘲笑

题目描述

编写一个程序,通过填充空格来解决数独问题。

一个数独的解法需遵循如下规则

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 '.' 表示。


一个数独。


答案被标成红色。

提示:

给定的数独序列只包含数字 1-9 和字符 '.' 。
你可以假设给定的数独只有唯一解。
给定数独永远是 9x9 形式的。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sudoku-solver
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

我们一行一行的放,如果能得到一个解,直接返回 true,然后剪枝条件如下述 check函数。

参考xiao_ben_zhu大佬图解

var solveSudoku = function (board) {
    
    
  let check = (x, y, val) => {
    
    
    // 一行或者一列有重复元素,剪掉
    for (let i = 0; i < 9; i++) {
    
    
      if (board[x][i] == val || board[i][y] == val) return true;
    }
    let xx = Math.floor(x / 3) * 3;
    let yy = Math.floor(y / 3) * 3;
    // 3x3宫格内重复的情况,剪掉
    for (let i = 0; i < 3; i++) {
    
    
      for (let j = 0; j < 3; j++) {
    
    
        if (board[xx + i][yy + j] == val) return true;
      }
    }
    return false; // 没有冲突情况
  }
  let dfs = (x, y) => {
    
    
    if (y == 9) {
    
    
      x++;
      y = 0;
      if (x == 9) return true; // 都填完了,直接返回 true
    }
    if (board[x][y] != '.') return dfs(x, y + 1);
    for (let i = 1; i < 10; i++) {
    
    
      if (check(x, y, String(i))) continue;
      board[x][y] = String(i);
      if (dfs(x, y + 1)) return true; // 如果往下走,能够解出数独,直接返回 true
      board[x][y] = '.'; // 回溯,因为往下走得不到一个解
    }
    return false;
  }
  dfs(0, 0);
  return board;
};

最后

文章产出不易,还望各位小伙伴们支持一波!

往期精选:

小狮子前端の笔记仓库

访问超逸の博客,方便小伙伴阅读玩耍~

学如逆水行舟,不进则退

猜你喜欢

转载自blog.csdn.net/weixin_42429718/article/details/108672616