1. <?php
    2. class Solution {
    3. /**
    4. * @param String[][] $board
    5. * @return NULL
    6. */
    7. function solveSudoku(&$board) {
    8. $n = count($board);
    9. for ($i = 0; $i < $n; $i++) {
    10. for ($j = 0; $j < $n; $j++) {
    11. if ($board[$i][$j] != '.') continue;
    12. for ($num = 1; $num < 10; $num++) {
    13. $board[$i][$j] = $num;
    14. if ($this->isValidSudoku($board) && $this->solveSudoku($board)) {
    15. return true;
    16. }
    17. // 先填入的值,在递归后续不满足,需要重置
    18. $board[$i][$j] = '.';
    19. }
    20. // 上面循环的值(1 - 9)没有满足的情况,则返回false,回溯到上一次填值。(表示此路不通)
    21. return false;
    22. }
    23. }
    24. return true;
    25. }
    26. public function isValidSudoku(array $sudo) {
    27. $n = count($sudo);
    28. $littleSquare = [];
    29. $col = [];
    30. for ($i = 0; $i < $n; $i++) {
    31. $row = [];
    32. for ($j = 0; $j < $n; $j++) {
    33. // '.' 跳过
    34. if ($sudo[$i][$j] == '.') continue;
    35. // 检查行
    36. if (isset($row[$sudo[$i][$j]])) {
    37. return false;
    38. } else {
    39. $row[$sudo[$i][$j]] = 1;
    40. }
    41. // 检查列
    42. if (isset($col[$j][$sudo[$i][$j]])) {
    43. return false;
    44. } else {
    45. $col[$j][$sudo[$i][$j]] = 1;
    46. }
    47. // 检查小正方形
    48. if (isset($littleSquare[floor($i / 3)][floor(($j / 3))][$sudo[$i][$j]])) {
    49. return false;
    50. } else {
    51. $littleSquare[floor($i / 3)][floor(($j / 3))][$sudo[$i][$j]] = 1;
    52. }
    53. }
    54. }
    55. return true;
    56. }
    57. }
    58. $sudo = [
    59. ["5","3",".",".","7",".",".",".","."],
    60. ["6",".",".","1","9","5",".",".","."],
    61. [".","9","8",".",".",".",".","6","."],
    62. ["8",".",".",".","6",".",".",".","3"],
    63. ["4",".",".","8",".","3",".",".","1"],
    64. ["7",".",".",".","2",".",".",".","6"],
    65. [".","6",".",".",".",".","2","8","."],
    66. [".",".",".","4","1","9",".",".","5"],
    67. [".",".",".",".","8",".",".","7","9"]
    68. ];
    69. $cls = new Solution();
    70. $ret = $cls->solveSudoku($sudo);
    71. if ($ret) {
    72. array_walk($sudo, function (&$v) {
    73. $v = implode(',', $v);
    74. });
    75. echo implode("\n", $sudo);
    76. } else {
    77. echo 'false';
    78. }