【问题标题】:Check if Sudoku solution is valid [closed]检查数独解决方案是否有效[关闭]
【发布时间】:2023-04-11 08:49:01
【问题描述】:

您已获得数独谜题的解决方案。编写代码以检查它是否是有效的解决方案。

您的函数签名应该是:
boolean isValid(int starti, int startj, int endi, int endj)

不熟悉数独的规则:

  • 网格大小为 9x9,分为 3x3 的 9 个区域
  • 每行必须包含 1-9 的所有数字
  • 每列必须包含 1-9 的所有数字
  • 每个 3x3 方格必须包含 1-9 的所有数字

我没有被问到这个问题,但在severalplaces 上看到了它。检查最后一条规则可能是有趣的部分

【问题讨论】:

  • 它仍然闻起来像家庭作业。
  • 除非需要整个网格区域,否则此函数签名似乎是错误的。一个 9x9 的数独矩阵作为参数会更好。
  • f.y.i 供其他读者参考,这是从 glassdoor interview question for google 链接的

标签: sudoku


【解决方案1】:
// rows
for (int i=0; i<9; i++) {
    std::bitset<9> filled;
    for (int j=0; j<9; j++)
        filled.set(grid[i][j] - 1);
    if (filled.count() != 9)
        return false;
}

// ... similar with the loops "swapped" to get the columns
// (or do both in one loop)

for (int i=0; i<9; i += 3)
    for (int j=0; j<9; j += 3) {
        std::bitset<9> filled;
        for (int k=0; k<3; k++)
            for (int l=0; l<3; l++)
                filled.set(grid[i+k][j+l] - 1);
        if (filled.count() != 9)
            return false;
    }

return true;

【讨论】:

  • 这是如何工作的?算法是什么?
  • @RaviRamadoss 这是一种蛮力算法,完全遵循数独规则集。首先,它使用std::bitsetstd::bitset.count 返回设置位数)检查每一行是否正好包含 9 个不同的数字。然后它以相同的方式检查每一列和每个块。
【解决方案2】:

对不起,我知道这一定是家庭作业,但我忍不住。想出一些东西真是太有趣了:-)

一勺装满 LINQ 的药就下去了:

public class Sudoku
{
    private int[][] sudoku;

    public Sudoku(int[][] sudoku)
    { 
        // TODO: Validate bounds and values
        this.sudoku = sudoku;
    }

    public bool Validate() =>
        VerticalLines.All(IsValid)
        && HorizontalLines.All(IsValid)
        && Squares.All(IsValid);

    IEnumerable<IEnumerable<int>> VerticalLines =>
        from line in sudoku select line;

    IEnumerable<IEnumerable<int>> HorizontalLines =>
        from y in Enumerable.Range(0, 9)
        select (
            from x in Enumerable.Range(0, 9)
            select sudoku[x][y]);

    IEnumerable<IEnumerable<int>> Squares =>
        from x in Enumerable.Range(0, 3)
        from y in Enumerable.Range(0, 3)
        select GetSquare(x, y);

    IEnumerable<int> GetSquare(int x, int y) =>
        from squareX in Enumerable.Range(0, 3)
        from squareY in Enumerable.Range(0, 3)
        select sudoku[x * 3 + squareX][y * 3 + squareY];

    bool IsValid(IEnumerable<int> line) => !(
        from item in line
        group item by item into g
        where g.Count() > 1
        select g)
        .Any();
}

这个解决方案的好处是,如果你说你想出了这个,没有老师会相信你;-)

【讨论】:

  • 我认为您的 Squares 属性可以这样表示: return Enumerable.Range(0, 3).Select(i => Enumerable.Range(0, 3).SelectMany(j => GetSquare (j, i)).ToList()); :)
  • @Yngve:哈哈.. 我也是这么想的。我已经改变了:-)
  • 太棒了!我很想看看老师们在校对这个 O_o 时的表情:)
  • 通过将有效性检查的结果保存在变量中,您将错过使有效性检查短路的机会。如果某些行无效,则无需检查列和正方形。
【解决方案3】:

SQL 允许您将规则定义为 CONSTRAINTS:无效的拼图被禁止并且不能存在。

        -- Domain with only values 1..9 allowed,
        -- used for both the {x,y,z} coordinates and the cell values.
CREATE DOMAIN one_nine
        AS INTEGER
        CHECK (value >= 1 AND value <= 9)
        ;

        -- Table containing exactly one sudoku puzzle.
        -- The zzz coordinate (the "box number") is formally redundant
        -- (since it is functionally dependant on {xxx,yyy})

DROP TABLE IF EXISTS sudoku3 CASCADE;
CREATE TABLE sudoku3
        ( yyy one_nine NOT NULL
        , xxx one_nine NOT NULL
        , zzz one_nine NOT NULL
        , val one_nine
        );

        -- First constraint: (x,y) is unique
ALTER TABLE sudoku3 ADD PRIMARY KEY (xxx,yyy);

        -- Three constraints for unique values for {rows,columns,boxes}
CREATE UNIQUE INDEX sudoku_xv ON sudoku3 (xxx,val);
CREATE UNIQUE INDEX sudoku_yv ON sudoku3 (yyy,val);
CREATE UNIQUE INDEX sudoku_zv ON sudoku3 (zzz,val);

        -- Create empty board.
INSERT INTO sudoku3 (yyy, xxx, zzz)
SELECT  1+(nn/9)
        , 1+(nn%9)
        , 1+3*((nn/3)%3)+1*(nn/27)
        -- generate_series() is postgres-specific
        FROM generate_series(0,80) AS nn;

现在,->val 成员可以更新,但生成的表永远不会违反四个约束中的任何一个(三个实际上是 INDEXES,但这在这里并不重要)。

检查一个完全有效的填充表意味着:检查是否有81个非NULL条目:

SELECT 1 AS result -- COUNT(*) 
    FROM sudoku3
    WHERE val IS NOT NULL
    HAVING COUNT(*) = 81
      ;

【讨论】:

  • 你应该在上面
  • 这一定是我读过的最疯狂但最酷的解决方案!谁会想到使用 SQL 约束来解决这个问题!我向你致敬!
【解决方案4】:

使用位集的 Java 实现:

public static boolean isValid(int[][] board) {
  //Check rows and columns 
  for (int i = 0; i < board.length; i++) {
    BitSet bsRow = new BitSet(9);
    BitSet bsColumn = new BitSet(9);
    for (int j = 0; j < board[i].length; j++) {
      if (board[i][j] == 0 || board[j][i] == 0) continue;
      if (bsRow.get(board[i][j] - 1) || bsColumn.get(board[j][i] - 1))
        return false;
      else {
        bsRow.set(board[i][j] - 1);
        bsColumn.set(board[j][i] - 1);
      }
    }
  }
  //Check within 3 x 3 grid
  for (int rowOffset = 0; rowOffset < 9; rowOffset += 3) {
    for (int columnOffset = 0; columnOffset < 9; columnOffset += 3) {
      BitSet threeByThree = new BitSet(9);
      for (int i = rowOffset; i < rowOffset + 3; i++) {
        for (int j = columnOffset; j < columnOffset + 3; j++) {
          if (board[i][j] == 0) continue;
          if (threeByThree.get(board[i][j] - 1))
            return false;
          else
            threeByThree.set(board[i][j] - 1);
        }
      }  
    }
  }
  return true;
}

【讨论】:

    【解决方案5】:

    这将是我在 ruby​​ 中的解决方案

    #Sudoku grid 9x9 with numbers between 1 and 9
    #three rules:
    #1) in any row all numbers between 1 and 9 have to be present
    #2) in any columns all numbers between 1 and 9 have to be present
    #3) in any of the 9 3x3 boxes all numbers between 1 and 9 have to be present 
    
    
    sudoku_correct =[[8,3,5,4,1,6,9,2,7],
                   [2,9,6,8,5,7,4,3,1],
                   [4,1,7,2,9,3,6,5,8],
                   [5,6,9,1,3,4,7,8,2],
                   [1,2,3,6,7,8,5,4,9],
                   [7,4,8,5,2,9,1,6,3],
                   [6,5,2,7,8,1,3,9,4],
                   [9,8,1,3,4,5,2,7,6],
                   [3,7,4,9,6,2,8,1,5]]
    
    sudoku_incorrect =[[8,3,5,4,1,6,9,2,7],
                     [2,9,6,8,5,7,4,3,1],
                     [4,1,7,2,9,3,6,5,8],
                     [5,6,9,1,3,4,7,8,2],
                     [1,2,3,6,7,8,5,4,9],
                     [7,4,8,5,2,9,1,6,3],
                     [6,5,2,7,8,1,3,9,4],
                     [9,8,1,3,4,5,2,7,6],
                     [3,7,4,9,6,2,8,1,1]]
    
    class Sudoku
    def initialize(s_arr)
      @sudoku_arr = s_arr
    end
    
    # given 9 integers makesure that you have 1 to 9
    def valid_contents?(set)
      set.each do |e|
        return false unless (1..9).include?(e)
      end
      return true
    end
    
    # check if set has no duplicates
    def has_no_duplicates?(set)
      set.uniq.size < set.size ? false : true
    end
    
    def valid_set?(set)
      valid_contents?(set) &&  has_no_duplicates?(set)
    end
    
    # obtain blocks of sudoku, given a grid
    def get_blocks(s_grid)
      blocks = []
      s_grid.each_slice(3) do |row_set|
        blocks_temp = [[],[],[]]
        row_set.each do |row|
          row.each_slice(3).with_index  do|s,i|
            blocks_temp[i] = blocks_temp[i] + s
          end
        end
        blocks +=  blocks_temp
      end
      blocks
    end
    
    
    def valid?(s_arr = @sudoku_arr)
      #check for row validity
      s_arr.each do |set|
        return false unless valid_set?(set)
      end
    
      #check for block validity
      get_blocks(s_arr).each do |set|
        return false unless valid_set?(set)
      end
    
      #check column validity
      s_arr.transpose.each do |set|
        return false unless valid_set?(set)
      end
    
      true
    end
    
    end
    
    
    puts  Sudoku.new(sudoku_correct).valid?
    puts  Sudoku.new(sudoku_incorrect).valid? 
    # output: True & False
    

    【讨论】:

      【解决方案6】:

      只使用一次数组迭代的解决方案。 通过数组的整个迭代,posRec 数组将在 ROW/COL/GRID 中具有每个数字的可用性。 如果 posRec 中缺少位,我们可以说数独不正确。

      #include <stdio.h>
      
      #define ROW 0
      #define COL 1
      #define GRID 2
      #define TRUE 1
      #define FALSE 0
      
      
      char sudoku_correct[9][9] ={{8,3,5,4,1,6,9,2,7},
                                  {2,9,6,8,5,7,4,3,1},
                                  {4,1,7,2,9,3,6,5,8},
                                  {5,6,9,1,3,4,7,8,2},
                                  {1,2,3,6,7,8,5,4,9},
                                  {7,4,8,5,2,9,1,6,3},
                                  {6,5,2,7,8,1,3,9,4},
                                  {9,8,1,3,4,5,2,7,6},
                                  {3,7,4,9,6,2,8,1,5}};
      
      char sudoku_incorrect[9][9] ={{8,3,5,4,1,6,9,2,7},
                                    {2,9,6,8,5,7,4,3,1},
                                    {4,1,7,2,9,3,6,5,8},
                                    {5,6,9,1,3,4,7,8,2},
                                    {1,2,3,6,7,8,5,4,9},
                                    {7,4,8,5,2,9,1,6,3},
                                    {6,5,2,7,8,1,3,9,4},
                                    {9,8,1,3,4,5,2,7,6},
                                    {3,7,4,9,6,2,8,1,1}};
      
      
      
      short posRec[9][3];
      
      int isValid(char a[][9]) {
         int i, j, val, gIndex;
      
         for(i=0; i <9; i++){
            posRec[i][ROW] = 0;
            posRec[i][COL] = 0;
            posRec[i][GRID] = 0;
         }
      
      
         for(i=0; i<9; i++) {
            for(j=0; j<9; j++) {
               val=a[i][j]-1; //convert to 0-8 array index
               if((posRec[val][ROW]>>i) & 0x1)
                  return FALSE;
               posRec[val][ROW] |= (0x1<<i);
      
      
               if((posRec[val][COL]>>j) & 0x1)
                  return FALSE;
               posRec[val][COL] |= (0x1<<j);
      
               gIndex = (j/3) + ((i/3) * 3);
               if((posRec[val][GRID]>>gIndex) & 0x1)
                  return FALSE;
               posRec[val][GRID] |= (0x1<<gIndex);
      
            }
         }
      
         for(i=0; i<9;i++){
      
            if(posRec[i][COL] != 0x1ff ||
               posRec[i][ROW] != 0x1ff ||
               posRec[i][GRID] != 0x1ff)
               return FALSE;
         }
      
         return TRUE;
      
      }
      
      int main(){
      
         printf("correct sudoku check = %s \n", isValid(sudoku_correct)?"CORRECT":"INCORRECT");
         printf("incorrect sudoku check = %s \n", isValid(sudoku_incorrect)?"CORRECT":"INCORRECT");
         return 0;
      }
      

      【讨论】:

        【解决方案7】:
        package Questions;
        
        public class SudukoSonChek {
        
            public static void main(String args[]) {
        
                int a[][] = { { 2, 4, 8, 3, 9, 5, 7, 1, 6 },
                        { 5, 7, 1, 6, 2, 8, 3, 4, 9 }, { 9, 3, 6, 7, 4, 1, 5, 8, 2 },
                        { 6, 8, 2, 5, 3, 9, 1, 7, 4 }, { 3, 5, 9, 1, 7, 4, 6, 2, 8 },
                        { 7, 1, 4, 8, 6, 2, 9, 5, 3 }, { 8, 6, 3, 4, 1, 7, 2, 9, 5 },
                        { 1, 9, 5, 2, 8, 6, 4, 3, 7 }, { 4, 2, 7, 9, 5, 3, 8, 6, 1 } };
        
                System.out.println(check(a));
            }
        
            public static boolean check(int arr[][]) {
                int i, j;
                int count[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                int count1[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                boolean b = true;
                for (i = 0; i < 9; i++) {
                    for (j = 0; j < 9; j++) {
        
                        if (count[arr[j][i]] > i) {
                            b = false;
                            return b;
                        }
                        if (count1[arr[i][j]] > i) {
                            b = false;
                            return b;
                        }
                        count1[arr[i][j]]++;
                        count[arr[j][i]]++;
                    }
        
                }
                return b;
            }
        
        }
        

        【讨论】:

        • 提供一面代码墙很少(如果有的话)是一个好的答案。请尝试至少提供一个简短的解释。
        • 所以一个已解决的数独板正好包含 9 个数字 1 到 9。这会检查这一点。
        • @WillJamieson 但数独板包含 1 到 9 每个数字中的 9 个,不一定是有效的已解决数独。例如,它可能有 9 行 123456789。
        【解决方案8】:

        参考@Stephen 的出色回答,这里是 C# 中的一个解决方案,不使用 LINQ,以显示两种方法之间的区别。

        此解决方案可处理 4x4 和 9x9 数独板。

        using System;
        using System.Collections.Generic;
        using System.IO;
        using System.Linq;
        
        namespace Sodoku
        {
            class Program
            {
                static void Main(string[] args)
                {
                    List<string> lines = new List<string>();
                    lines.Add("4;1,4,2,3,2,3,1,4,4,2,3,1,3,1,4,2");
                    lines.Add("4;2,1,3,2,3,2,1,4,1,4,2,3,2,3,4,1");
                    lines.Add("9;5,3,4,6,7,8,9,1,2,6,7,2,1,9,5,3,4,8,1,9,8,3,4,2,5,6,7,8,5,9,7,6,1,4,2,3,4,2,6,8,5,3,7,9,1,7,1,3,9,2,4,8,5,6,9,6,1,5,3,7,2,8,4,2,8,7,4,1,9,6,3,5,3,4,5,2,8,6,1,7,9");
                    lines.Add("9;8,7,1,4,6,9,3,5,2,4,2,6,3,5,1,8,9,7,5,9,3,7,2,8,4,6,1,3,5,2,9,4,7,6,1,8,6,4,9,1,8,2,5,7,3,1,8,7,5,3,6,2,4,9,9,6,4,2,1,3,7,8,5,7,3,8,6,9,5,1,2,4,2,1,5,8,7,4,9,3,6");
                    lines.Add("9;1,2,7,5,3,9,8,4,6,4,5,3,8,6,1,7,9,2,8,9,6,4,7,2,1,5,3,2,8,9,3,1,7,4,6,5,3,6,5,2,8,4,9,1,7,7,4,1,9,5,6,3,2,8,9,7,4,6,2,8,5,3,1,5,1,2,7,4,3,6,8,9,6,3,8,1,9,5,2,7,4");
                    lines.Add("4;1,4,4,3,2,3,4,4,3,2,3,1,3,1,4,2");
        
                    foreach (var line in lines)
                    {
                        var tokens = line.Split(';');
        
                        var NxN = int.Parse(tokens[0]);
                        var nums = tokens[1].Trim().Split(',').Select(int.Parse).ToArray();
        
                        // Copy into Grid. Input is in row major form.
                        var grid = new int[NxN, NxN];
                        {
                            int i = 0;
                            for (int row = 0; row < NxN; row++)
                            {
                                for (int col = 0; col < NxN; col++)
                                {
                                    grid[row, col] = nums[i];
                                    i++;
                                }
                            }
                        }
        
                        int violations = 0;
        
                        // Check if each column passes tests for Sodoku.
                        {                   
                            for (int row = 0; row < NxN; row++)
                            {
                                var tempArray = new int[NxN];
        
                                for (int col = 0; col < NxN; col++)
                                {
                                    tempArray[col] = grid[row, col];
                                }
        
                                if (IfArrayPassesSodoku(tempArray) == false)
                                {
                                    violations++;
                                }
                            }
                        }
        
                        // Check if each row passes tests for Sodoku.
                        {
                            for (int row = 0; row < NxN; row++)
                            {
                                var tempArray = new int[NxN];
        
                                for (int col = 0; col < NxN; col++)
                                {
                                    tempArray[col] = grid[col, row];
                                }
        
                                if (IfArrayPassesSodoku(tempArray) == false)
                                {
                                    violations++;
                                }
                            }
                        }
        
                        // Check if each sub-grid passes tests for Sodoku.
                        // In 9x9 Sodoku, there are 9 subgrids of 3x3 each.
                        {
                            int NxNsub = (int)Math.Sqrt(NxN); // Length of side of sub-grid, for a 9x9 board this will be 3.
        
                            for (int row = 0; row < NxN; row += NxNsub)
                            {
                                for (int col = 0; col < NxN; col += NxNsub)
                                {
                                    var tempArray = new int[NxN];
                                    int index = 0;
                                    for (int i = 0; i < NxNsub; i++)
                                    {
                                        for (int j = 0; j < NxNsub; j++)
                                        {
                                            tempArray[index] = grid[i + col, j + row];
                                            index++;
                                        }    
                                    }
                                    if (IfArrayPassesSodoku(tempArray) == false)
                                    {
                                        violations++;
                                    }
                                }
                            }
        
                        }
        
                        Console.WriteLine(violations == 0 ? "True" : "False");
        
                        // Correct output is:
                        // True
                        // False
                        // True
                        // True
                        // True
                        // False
                    }
        
                    Console.ReadKey();
                }
        
                /// <summary>
                /// Checks to see if one-dimensional array passes Sodoku rules:
                /// 1. Digits range from 1 to N.
                /// 2. No repeating digits.        
                /// Could be way more efficient, but this solution is more readable compared to other concise forms.
                /// </summary>
                /// <param name="array">Array.</param>
                /// <returns>True if one-dimensional array passes Sodoku rules.</returns>
                static bool IfArrayPassesSodoku(int[] array)
                {
                    int violations = 0;
        
                    // Check for repeating digits.
                    bool ifRepeatedDigits = (array.Distinct().ToArray().Length != array.Length);
                    if (ifRepeatedDigits == true)
                    {
                        return false;
                    }
        
                    // Check to see that it contains the digits 1 to N.
                    var sorted = array.OrderBy(o => o).ToArray();
        
                    if (array.Length == 4)
                    {
                        if (sorted[0] != 1 || sorted[3] != 4)
                        {
                            return false;
                        }
                    }
                    else if (array.Length == 9)
                    {
                        if (sorted[0] != 1 || sorted[8] != 9)
                        {
                            return false;
                        }
                    }
                    else
                    {
                        Console.Write("Error E5234. Invalid grid size.\n");
                        return false;
                    }
        
                    return true;
                }
            }
        }
        

        【讨论】:

          【解决方案9】:

          我有一个类似的任务,输入来自标准输入。

          我用过套装。 将元素放在正确的行、列和正方形(在我的代码中称为框)。 如果 3 个集合的大小都是 9,则有效。

          #include <iostream>
          #include <set>
          
          int main()
          {
          
          //decl
          std::set<int> row[9];
          std::set<int> column[9];
          std::set<int> box[9];
          
          
          //read & store
          for (int i = 0; i < 9; ++i)
          {
              for (int j = 0; j < 9; ++j)
              {
                  int val;
                  std::cin >> val;
                  if ((val >= 1) && (val <= 9))
                  {
                      row[i].insert(val);
                      column[j].insert(val);
                      int k = j / 3 + i / 3 + i / 3 + i / 3;
                      box[k].insert(val);
                  }
              }
          }
          
          //check
          bool l = true;
          int i = 0;
          while (l && i < 9)
          {
              l = row[i].size() == 9;
              ++i;
          }
          
          if (!l) std::cout << "Invalid" << std::endl;
          else
          {
              bool l = true;
              int i = 0;
              while (l && i < 9)
              {
                  l = column[i].size() == 9;
                  ++i;
              }
          
              if (!l) std::cout << "Invalid" << std::endl;
              else
              {
                  bool l = true;
                  int i = 0;
                  while (l && i < 9)
                  {
                      l = box[i].size() == 9;
                      ++i;
                  }
          
                  if (!l) std::cout << "Invalid" << std::endl;
                  else std::cout << "Valid" << std::endl;
              }
          }
          
          return 0;
          

          }

          【讨论】:

            【解决方案10】:

            我认为我的解决方案很简洁,但如果其他人的解决方案显然也是如此。无论如何,我认为这是我在 2014 年 7 月 11 日为面试问题所做的一个非常清晰易读的 ruby​​ 答案:

            ## Returns true iff the given string is a valid sudoku solution
            def is_valid_solution(grid)
              return false unless grid.is_a? String and grid.size == 9 * 9
              validate_rows(grid) and validate_columns(grid) and validate_boxes(grid)
            end
            
            ## Returns true iff the set is the chars "1", "2", ..., "9"
            def is_valid_set(set)
              return false if set.size != 9
              (1..9).each do | x |
                return false unless set.include?(x.to_s)
              end
              true
            end
            
            def validate_rows(grid)
              (0...9).each do | row |
                index = row * 9
                return false unless is_valid_set(grid[index, 9])
              end
              true
            end
            
            def validate_columns(grid)
              (0...9).each do | index |
                column = (index...81).step(9).to_a.map { | i | grid[i] }.join
                return false unless is_valid_set(column)
              end
              true
            end
            
            ## This is ugly, but I'm running out of time...
            TOP_LEFT_INDICES =  [ 0,  1,  2,  9, 10, 11, 18, 19, 20]
            TOP_MID_INDICES =   [ 3,  4,  5, 12, 13, 14, 21, 22, 23]
            TOP_RIGHT_INDICES = [ 6,  7,  8, 15, 16, 17, 24, 25, 26]
            MID_LEFT_INDICES =  [27, 28, 29, 36, 37, 38, 45, 46, 47]
            MID_MID_INDICES =   [30, 31, 32, 39, 40, 41, 48, 49, 50]
            MID_RIGHT_INDICES = [33, 34, 35, 42, 43, 44, 51, 52, 53]
            BOT_LEFT_INDICES =  [54, 55, 56, 63, 64, 65, 72, 73, 74]
            BOT_MID_INDICES =   [57, 58, 59, 66, 67, 68, 75, 76, 77]
            BOT_RIGHT_INDICES = [60, 61, 62, 69, 70, 71, 78, 79, 80]
            BOX_INDICES = [TOP_LEFT_INDICES, TOP_MID_INDICES, TOP_RIGHT_INDICES,
                           MID_LEFT_INDICES, MID_MID_INDICES, MID_RIGHT_INDICES,
                           BOT_LEFT_INDICES, BOT_MID_INDICES, BOT_RIGHT_INDICES]
            
            def validate_boxes(grid)
              BOX_INDICES.each do | indices |
                box = indices.map { | i | grid[i] }.join
                return false unless is_valid_set(box)
              end
              true
            end
            

            【讨论】:

              【解决方案11】:

              可以在单个循环中验证行和列

              public class SudokuChecker {
              
              static int[][] sMatrix = {
              
                  {5,3,4,6,7,8,9,1,2},
                  {6,7,2,1,9,5,3,4,8},
                  {1,9,8,3,4,2,5,6,7},
                  {8,5,9,7,6,1,4,2,3},
                  {4,2,6,8,5,3,7,9,1},
                  {7,1,3,9,2,4,8,5,6},
                  {9,6,1,5,3,7,2,8,4},
                  {2,8,7,4,1,9,6,3,5},
                  {3,4,5,2,8,6,1,7,9}
              
              };
              
              public static void main(String[] args) {
                  if (rowColumnCheck() && boxCheck()) {
                      System.out.println("Valid!");
                  } else {
                      System.out.println("Invalid!");
                  }
              }
              
              private static boolean boxCheck() {
                  for (int i = 0; i < sMatrix.length; i += 3) {
                      for (int j = 0; j < sMatrix.length; j += 3) {
                          boolean[] gridMatrix = new boolean[9];
                          for (int k = i; k < 3 + i; k++) {
                              for (int l = j; l < 3 + j; l++) {
                                  int currentNumber = sMatrix[k][l];
                                  if (currentNumber < 1 || currentNumber > 9) {
                                      return false;
                                  }
                                  gridMatrix[currentNumber - 1] = true;
                              }
                          }
                          for (boolean booleanValue : gridMatrix) {
                              if (!booleanValue) {
                                  return false;
                              }
                          }
                      }
                  }
                  return true;
              }
              
              private static boolean rowColumnCheck() {
                  for (int i = 0; i < 9; i++) {
                      boolean[] rowArray = new boolean[9];
                      boolean[] columnArray = new boolean[9];
                      for (int j = 0; j < 9; j++) {
                          int currentNumberRow = sMatrix[i][j];
                          int currentNumberColumn = sMatrix[j][i];
                          if ((currentNumberRow < 1 || currentNumberRow > 9) && (currentNumberColumn < 1 || currentNumberColumn > 9)) {
                              return false;
                          }
                          rowArray[currentNumberRow - 1] = true;
                          columnArray[currentNumberColumn - 1] = true;
              
                      }
                      for (boolean booleanValue : rowArray) {
                          if (!booleanValue) {
                              return false;
                          }
                      }
                      for (boolean booleanValue : columnArray) {
                          if (!booleanValue) {
                              return false;
                          }
                      }
                  }
                  return true;
              }
              

              }

              【讨论】:

              • 只检查sum = 45 是否有效?如果列有37, 1, 1, 1, 1, 1, 1, 1, 1 怎么办?你的逻辑也有缺陷——如果第一行是正确的successTillNow 将是true——如果第二行是错误的,它将返回successTillNow 的当前值,它仍然是true
              • 嗨,Stanley.. 我已根据您的 cmets 更改了代码。如果您发现我已经工作并现在放置了正确的解决方案,请检查并删除负号。
              • @DStanley:我查看了很多解决方案,想知道为什么没有人使用检查每个正方形的总和是否为 45。它可以很容易地推广到一个奇数的数独谜题。
              猜你喜欢
              • 1970-01-01
              • 2022-08-07
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多