摘要:題目要求也就是給出一個解決數獨的方法,假設每個數獨只有一個解決方案。并將當前的假象結果帶入下一輪的遍歷之中。如果最終遍歷失敗,則逐級返回,恢復上一輪遍歷的狀態,并填入下一個合理的假想值后繼續遍歷。
題目要求
Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by the character ".". You may assume that there will be only one unique solution.
也就是給出一個解決數獨的方法,假設每個數獨只有一個解決方案。
思路一:不使用數據結構不使用數據結構意味著我們自己在每一次遇到一個空格時,需要在board中對該空格所在的行,列以及方塊進行遍歷,判斷填入什么數字是合適的。并將當前的假象結果帶入下一輪的遍歷之中。如果最終遍歷失敗,則逐級返回,恢復上一輪遍歷的狀態,并填入下一個合理的假想值后繼續遍歷。這里涉及的時間復雜度是很高的,畢竟只是遍歷整個board就需要O(n^2),如果遇到一個空格還需要O(n)來判斷填入值是否合理。總共O(n^3)的時間復雜度。代碼如下:
public void solveSudoku(char[][] board) { if(board == null || board.length == 0) return; solve(board); } public boolean solve(char[][] board){ for(int i = 0; i < board.length; i++){ for(int j = 0; j < board[0].length; j++){ if(board[i][j] == "."){ for(char c = "1"; c <= "9"; c++){//trial. Try 1 through 9 if(isValid(board, i, j, c)){ board[i][j] = c; //Put c for this cell if(solve(board)) return true; //If it"s the solution return true else board[i][j] = "."; //Otherwise go back } } return false; } } } return true; } //橫 豎 方塊 private boolean isValid(char[][] board, int row, int col, char c){ for(int i = 0; i < 9; i++) { if(board[i][col] != "." && board[i][col] == c) return false; //check row if(board[row][i] != "." && board[row][i] == c) return false; //check column if(board[3 * (row / 3) + i / 3][ 3 * (col / 3) + i % 3] != "." && board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] == c) return false; //check 3*3 block } return true; }思路二:使用二維布爾數組分別記錄行列和方塊的所有值情況
我們使用boolean[][] rows, boolean[][] columns, boolean[][] squares分別記錄行列和方塊的所有值情況。其中rowsi記錄i行是否有值j,columnsi記錄i列是否有值j,squaresi記錄第i個方塊是否有值j。總體思路還是和上一個差不多,只是通過消費了存儲空間的基礎上提高了性能。
public void solveSudoku2(char[][] board) { int length = board.length; //記錄第i行是否出現j數字 boolean[][] rows = new boolean[length][length+1]; //第i列是否出現j數字 boolean[][] columns = new boolean[length][length+1]; //第i個小方格是否出現j數字。 boolean[][] squares = new boolean[length][length+1]; for(int i = 0 ; i < length ; i++){ for(int j = 0 ; j更多解法 看到一個解答 效率很高 但是不是很明白 希望看到的大神解答一下
private boolean solver(int idx, char[][] board, ArrayListstack, int[] store) { if (idx == stack.size()) return true; int n = stack.get(idx); int y = n / 9; int x = n - y * 9; int h = y; int v = 9 + x; int b = 18 + (y / 3 * 3 + x / 3); int available = ~store[h] & ~store[v] & ~store[b] & 0b111111111; while (available > 0) { int bit = available & -available; int num = Integer.numberOfTrailingZeros(bit); store[h] ^= bit; store[v] ^= bit; store[b] ^= bit; board[y][x] = (char)(num + "1"); if (solver(idx + 1, board, stack, store)) return true; store[h] ^= bit; store[v] ^= bit; store[b] ^= bit; // board[y][x] = "."; available &= available - 1; } return false; } public void solveSudoku3(char[][] board) { ArrayList stack = new ArrayList<>(); // int[] stack = new int[81]; int len = 0; int[] store = new int[27]; // 0-8 h, 9 - 17 v, 18 - 26 b for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (board[i][j] == ".") stack.add(i * 9 + j); else { int h = i; int v = 9 + j; int b = 18 + (i / 3 * 3 + j / 3); store[h] ^= 1 << board[i][j] - "1"; store[v] ^= 1 << board[i][j] - "1"; store[b] ^= 1 << board[i][j] - "1"; } } } solver(0, board, stack, store); }
想要了解更多開發技術,面試教程以及互聯網公司內推,歡迎關注我的微信公眾號!將會不定期的發放福利哦~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/67363.html
Problem Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must satisfy all of the following rules: Each of the digits 1-9 must occur exactly once in each row.Each ...
摘要:的可以由確定,這一點在里面的位置可以由確定所以每確定一行,每一個值都可以被轉換到一個之中。如果允許的空間復雜度,可以設置一個二維數組來用來判斷是否在里重現了重復的數字。將一個數字的每一個位上表示每一個數字。 Leetcode[36] Valid Sudoku Determine if a Sudoku is valid, according to: Sudoku Puzzles - ...
摘要:如果重復則不合法,否則極為合法。在這里我們使用數組代替作為存儲行列和小正方形的值得數據結構。我存儲這所有的行列小正方形的情況,并判斷當前值是否重復。外循環則代表對下一行,下一列和下一個小正方形的遍歷。 題目要求 Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku boa...
摘要:要求我們判斷已經填入的數字是否滿足數獨的規則。即滿足每一行每一列每一個粗線宮內的數字均含,不重復。沒有數字的格子用字符表示。通過兩層循環可以方便的檢查每一行和每一列有沒有重復數字。對于每個,作為縱坐標,作為橫坐標。 題目詳情 Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.The Sudo...
摘要:每天會折騰一道及以上題目,并將其解題思路記錄成文章,發布到和微信公眾號上。三匯總返回目錄在月日月日這半個月中,做了匯總了數組知識點。或者拉到本文最下面,添加的微信等會根據題解以及留言內容,進行補充,并添加上提供題解的小伙伴的昵稱和地址。 LeetCode 匯總 - 2019/08/15 Create by jsliang on 2019-08-12 19:39:34 Recently...
閱讀 954·2021-11-25 09:43
閱讀 2290·2019-08-30 15:55
閱讀 3153·2019-08-30 15:44
閱讀 2052·2019-08-29 16:20
閱讀 1452·2019-08-29 12:12
閱讀 1608·2019-08-26 12:19
閱讀 2282·2019-08-26 11:49
閱讀 1711·2019-08-26 11:42