zoukankan      html  css  js  c++  java
  • LeetCode

    Sudoku Solver

    2014.2.28 21:30

    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.

    A sudoku puzzle...

    ...and its solution numbers marked in red.

    Solution:

      My solution to this problem is by DFS and backtracking. The difference is that I added some optimization strategies to the program:

        1. [7][6] can be represented as [7 * 9 + 6], you don't have to calculate it every time, store the coordinates in an array instead.

        2. [69] can be represented as [69 / 9][69 % 9], you don't have to calculate it every time, becasue '/' and '%' are expensive operators.

        3. When you've filled in a blank, where is the next blank to fill? You can find the next blank in O(1) time, instead of scanning the whole board.

        4. When one attempt failed, how do you backtrack efficiently? With a <vector>, pop_back() and push_back() is a good choice.

      The Dancing Links Algorithm seems to be a very exquisite way to solve Sudoku, but here it might be way too complicated for an interview question. Perhaps I'm just too lazy to learn it, spare me~(>_<)

      Total time complexity is O((n^2)!), but it would never appear that large. Space complexity is O(n^2).

    Accepted code:

      1 // 1AC, very well, avoiding too much '/' and '%' will speed up the program.
      2 #include <cmath>
      3 #include <vector>
      4 using namespace std;
      5 
      6 class Solution {
      7 public:
      8     void solveSudoku(vector<vector<char> > &board) {
      9         n2 = (int)board.size();
     10         if (n2 == 0) {
     11             return;
     12         } else if (n2 == 1) {
     13             board[0][0] = '1';
     14             return;
     15         }
     16         
     17         n = (int)sqrt(1.0 * n2);
     18         n4 = n2 * n2;
     19         
     20         int i, j;
     21         row.resize(n2);
     22         for (i = 0; i < n2; ++i) {
     23             row[i].resize(n2);
     24         }
     25         col.resize(n2);
     26         for (i = 0; i < n2; ++i) {
     27             col[i].resize(n2);
     28         }
     29         block.resize(n2);
     30         for (i = 0; i < n2; ++i) {
     31             block[i].resize(n2);
     32         }
     33         bc.resize(n2);
     34         for (i = 0; i < n2; ++i) {
     35             bc[i].resize(n2);
     36         }
     37         row_coordinate.resize(n4);
     38         col_coordinate.resize(n4);
     39         for (i = 0; i < n4; ++i) {
     40             row_coordinate[i] = i / n2;
     41             col_coordinate[i] = i % n2;
     42         }
     43         
     44         for (i = 0; i < n2; ++i) {
     45             for (j = 0; j < n2; ++j) {
     46                 row[i][j] = col[i][j] = block[i][j] = 0;
     47             }
     48         }
     49         
     50         for (i = 0; i < n2; ++i) {
     51             for (j = 0; j < n2; ++j) {
     52                 bc[i][j] = i / n * n + j / n;
     53             }
     54         }
     55         
     56         cc = 0;
     57         for (i = 0; i < n2; ++i) {
     58             for (j = 0; j < n2; ++j) {
     59                 if (board[i][j] != '.') {
     60                     // it is a digit
     61                     row[i][board[i][j] - '1'] = 1;
     62                     col[j][board[i][j] - '1'] = 1;
     63                     block[bc[i][j]][board[i][j] - '1'] = 1;
     64                 } else {
     65                     empty_slots.push_back(i * n2 + j);
     66                     ++cc;
     67                 }
     68             }
     69         }
     70         
     71         suc = false;
     72         dfs(board);
     73         
     74         // perform cleanup operations
     75         for (i = 0; i < n2; ++i) {
     76             row[i].clear();
     77             col[i].clear();
     78             block[i].clear();
     79             bc[i].clear();
     80         }
     81         row.clear();
     82         col.clear();
     83         block.clear();
     84         bc.clear();
     85         empty_slots.clear();
     86         row_coordinate.clear();
     87         col_coordinate.clear();
     88     }
     89 private:
     90     bool suc;
     91     int n, n2, n4;
     92     int cc;
     93     vector<vector<int> > row, col, block;
     94     vector<vector<int> > bc;
     95     vector<int> empty_slots;
     96     vector<int> row_coordinate, col_coordinate;
     97     
     98     void dfs(vector<vector<char> > &board) {
     99         if (suc) {
    100             return;
    101         }
    102         if (cc == 0) {
    103             suc = true;
    104             return;
    105         }
    106 
    107         int r, c;
    108         int i;
    109 
    110         r = row_coordinate[empty_slots[cc - 1]];
    111         c = col_coordinate[empty_slots[cc - 1]];
    112         for (i = 0; i < n2; ++i) {
    113             if (row[r][i] || col[c][i] || block[bc[r][c]][i]) {
    114                 continue;
    115             }
    116             row[r][i] = 1;
    117             col[c][i] = 1;
    118             block[bc[r][c]][i] = 1;
    119             empty_slots.pop_back();
    120             --cc;
    121             board[r][c] = (i + '1');
    122             
    123             dfs(board);
    124             if (suc) {
    125                 return;
    126             }
    127             
    128             row[r][i] = 0;
    129             col[c][i] = 0;
    130             block[bc[r][c]][i] = 0;
    131             empty_slots.push_back(r * n2 + c);
    132             ++cc;
    133             board[r][c] = '.';
    134         }
    135     }
    136 };
  • 相关阅读:
    [CSAPP笔记][第九章虚拟存储器][吐血1500行]
    [CSAPP笔记][第六章存储器层次结构]
    [CSAPP笔记][第八章异常控制流][呕心沥血千行笔记]
    好吧,刚把CSDN搬家到博客园。。记录一发
    [CSAPP笔记][第二章信息的表示和处理]
    综合练习:词频统计
    组合数据类型综合练习:英文词频统计
    熟悉常用的Linux操作
    1.大数据概述
    语义分析
  • 原文地址:https://www.cnblogs.com/zhuli19901106/p/3574405.html
Copyright © 2011-2022 走看看