leetcode36&37_SudukuSolver

36题:

一.问题描述

Determine if a Sudoku is valid, according to:  Sudoku Puzzles - The Rules.
The Sudoku board could be partially filled, where empty cells are filled with the character  '.'.


A partially filled sudoku which is valid.

Note:
A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.

即判断当前部分填充的数独是否是有效的,即每一列,每一行,每一个九宫格内没有重读的数字。

二.代码编写

主要思想就是为每一行,每一列,每一个九宫格建立一个flag列表,然后遍历整个数独矩阵,去填充flag列表。flag列表内的每个元素是一个整数,

每次遍历到的非'.'数字,则对相应flag列表的int做加法,x = 10**int(board[i][j]),这样最后得到的int的大于1的位置则代表该列/行/九宫格内有重复数字,

则该数独矩阵不合法。代码如下:

import math
class Solution(object):
    def is_ok(self,x):
        '''
        type x: int
        rtype: bool
        '''
        for i in str(x):
            if i=='0' or i=='1':
                continue
            else:
                return False
        return True
    def isValidSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: bool
        """
        len_bo = len(board)
        len_bo_sq = int(math.sqrt(len_bo))
        H = [0 for i in range(len_bo)]
        S = [0 for i in range(len_bo)]
        Z = [[0 for i in range(len_bo_sq)] for j in range(len_bo_sq)]
        for i in range(len_bo):
            for j in range(len_bo):
                if board[i][j] == '.':
                    continue
                x = 10**int(board[i][j])
                H[i] += x
                S[j] += x
                Z[i/3][j/3] += x
        for i in range(len_bo):
            if self.is_ok(H[i]) == False:
                return False
            if self.is_ok(S[i]) == False:
                return False
        for i in range(len_bo_sq):
            for j in range(len_bo_sq):
                if self.is_ok(Z[i][j]) == False:
                    return False
        return True
对上述题目描述中的矩阵而言,其三个flag列表值如下:
行:H = [0010101000,
     1001100010,
     1101000000,
     0101001000,
     0100011010,
     0011000100,
     0101000100,
     1000110010,
     1110000000]

列:略- -
九宫格:Z=[

   [1101101000,1010100010,0001000000],
   [0110010000,0101001100,0001001010],
   [0001000000,1100010010,1110100100]
  ]

37.Sudoku Solver

一.问题描述:

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...

对数独求解,基本规则使最后填满的数独是valid即可,假设解是唯一的。

二.代码编写:

典型的回溯思想(DFS)求解,(类似于走迷宫,走不下去了就回溯),具体思想就是对空格子由1到9填充(这里首先要选择当前位置的valid解),

填好了之后填下一个。

算法编写的思想就是从第一个位置开始找,如果该位置不为空,则对该位置进行填充,如果填充之后数独是valid的话,再判断之后的剩下位置是否valid(递归算法)。

判断valid我本来直接用的36的算法,结果TLE了,上网搜了一下发现可以优化valid的算法。也就是说只要判断当前填充进来的数字是否在对应行、列、九宫格中已经存在,

只要存在就返回False。代码如下:

class Solution(object):
    def isValidSudoku(self, board,row,col,s):
         # 只要判断当前加进去的[row][col]位置的数字是否valid即可,因为之前的数独是valid的
         # 也就是只要判断row行没有s,col列没有s,九宫格内没有s即可
        """
        :type board: List[List[str]]
        :type row: int
        :type col: int
        :type s: str
        :rtype: bool
        """
        len_board = len(board)
        for i in range(len_board):
            if board[row][i] == s:
                return False
            if board[i][col] == s:
                return False
        m = 3*(row/3)
        n = 3*(col/3)
        for i in range(m, m+3):
            for j in range(n, n+3):
                if board[i][j] == s:
                    return False
        return True

    def dfs(self, board, row, col):
        len_board = len(board)
        if col >= len_board:
            row += 1
            col = 0
        if row >= len_board:
            return True
        if board[row][col] == '.':
            for i in range(1, 10):
                #board[row][col] = str(i)
                if self.isValidSudoku(board,row,col,str(i)) == True:
                    board[row][col] = str(i)
                    if self.dfs(board, row, col + 1) == True:
                        return True
                    board[row][col] = '.'
            return False
        else:
            return self.dfs(board, row, col+1)
        return False

    def solveSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: void Do not return anything, modify board in-place instead.
        """
        self.dfs(board, 0, 0)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值