每日算法【数组】 - 有效的数独

132 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情

好好学习,天天刷题~~

今日份刷题有效的数独记录如下:

题目描述

请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。

数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

注意:

  • 一个有效的数独(部分已被填充)不一定是可解的。
  • 只需要根据以上规则,验证已经填入的数字是否有效即可。
  • 空白格用 '.' 表示。

image.png

image.png

解法一:简单思路法

根据题目的三个要求,数字1-9每一行,每一列,每3x3宫格只能出现1次,那么我们可以逐一判断实现即可。本次代码使用创建new map,利用map.has方法判断在这一区域内是否存在相同的数字,如果有,直接返回true即可。代码如下:

var isValidSudoku = function(board) {
for(var p=0;p<3;p++){
    for(var k=0;k<3;k++){
      var arr1 = new Map();
      for(var m=k*3;m<(k*3+3);m++){
        for(var n=p*3;n<(p*3+3);n++){
          if(arr1.has(board[m][n])&&board[m][n]!='.'){
            return false;
          }
          arr1.set(board[m][n],(m+1)*(n+1));
        }
      }
  }
  }
  
  for(var i=0;i<9;i++){ 
    var arr = new Map();
    var arr2 = new Map();
    for(var j =0;j<9;j++){
      if(arr.has(board[i][j])&&board[i][j]!='.'){
        return false;
      }
      arr.set(board[i][j],j);
      if(arr2.has(board[j][i])&&board[j][i]!='.'){
        return false;
      }
      arr2.set(board[j][i],j);
    }
  }
  return true;
};

提交结果如下:

image.png

解法二:一次遍历法

  • 分别定义横向,竖向的二维数组和3x3九宫格三维数组
  • 开始遍历循环,即9x9,如果判断当前位置不为空,则拿到索引所在占位的index加1。
  • 最后直接判断当前占位的计数是否大于1,如果大于1的话说明有重复的数字,返回false即可。
  • 以上占位均无大于1的情况,则返回true。 代码如下:
var isValidSudoku = function(board) {
  var r = new Array(9).fill(0).map(item=>new Array(9).fill(0));
  var c = new Array(9).fill(0).map(item=>new Array(9).fill(0));
  var a = new Array(3).fill(0).map(item=>new Array(3).fill(0).map(item=>new Array(9).fill(0)));
  for(var i=0;i<9;i++){
    for(var j=0;j<9;j++){
      if(board[i][j]!='.'){
        var index = Number(board[i][j]) - 1;
        r[i][index]++;
        c[j][index]++;
        a[Math.floor(i/3)][Math.floor(j/3)][index]++
        if(r[i][index]>1 || c[j][index]>1 || a[Math.floor(i/3)][Math.floor(j/3)][index] >1){
            return false
        }
      }
    }
  }
  return true;
};

提交结果情况大致同上个解法。