[几个Python技巧]Valid Sudoku

 一、题目

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

 

二、解析

判断给定的数独是否满足规则,即每行中没有重复元素、每列中没有重复元素、每个3*3的块中也没有重复元素

思路很简单,暴力即可,但从这题中学到了好多个技巧。

方法1是纯粹的遍历,当然效率也不高,超越27%;方法2经过改写,思路一样,超越81%

 

三、代码

方法1

class Solution(object):
    def isValidSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: bool
        """
        for i in range(9):
            cur = []
            for j in range(9):
                #check line
                if board[i][j] in cur:
                    return False
                else:
                    if board[i][j] != ".":
                        cur.append(board[i][j])
                    else:
                        pass
                lenCur = len(cur)
                lenSet = len(set(cur))
                if lenCur != lenSet:
                    return False
                else:
                    pass
                
        for i in range(9):
            cur = []
            for j in range(9):
                #check col
                if board[j][i] in cur:
                    return False
                else:
                    if board[j][i] != ".":
                        cur.append(board[j][i])
                    else:
                        pass
                lenCur = len(cur)
                lenSet = len(set(cur))
                if lenCur != lenSet:
                    return False
                else:
                    pass
        
        for a in range(0, 9, 3):
            for b in range(0, 9, 3):
                cur = []
                for i in range(a, a + 3, 1):
                    for j in range(b, b + 3, 1):
                        if board[i][j] in cur:
                            return False
                        else:
                            if board[i][j] != ".":
                                cur.append(board[i][j])
                            else:
                                pass
                        lenCur = len(cur)
                        lenSet = len(set(cur))
                        if lenCur != lenSet:
                            return False
                        else:
                            pass
        
        return True
                
                
                

可以看出,方法1中纯粹是遍历了9*9中的每个元素,用原始的list, set等操作来解决。

 

方法2:

class Solution(object):
    def isValidSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: bool
        """
        for row in board:
            if not self.isValid(row):
                return False
        
        for col in zip(*board):
            if not self.isValid(col):
                return False
        
        for i in (0, 3, 6):
            for j in (0, 3, 6):
                square = [board[x][y] for x in range(i, i + 3) for y in range(j, j + 3)]
                if not self.isValid(square):
                    return False
        
        return True
        
    def isValid(self, s):
        unit = [i for i in s if i != '.']
        return len(unit) == len(set(unit))
   
                
                
                

 

四、总结

1.以后再遇到通过遍历得到list的过程,使用lambda表达式写,如:

unit = [i for i in s if i != '.']

2.对于已经是list的数据类型,不要再重复遍历了,直接对其进行操作即可,如:

for row in board, 这里board是[[],[],...],row是[]

3.能不开变量就不要开变量,如:

rst = self.isValid(row)

if not rst:

    return False    

应写程

if not self.isValid(row):
  return False

虽然只是很小一步,但是就从超越60%上升到了80%。

5.遍历大法:

for index, content in enumurate(board):  index是索引,content是值。等同于for i  in range(len(board)):print i, board[i],好看许多

6.zip:拉链函数

board1=[[1,2,3],[4,5,6],[7,8,9]]
board2=[[9,8,7],[6,5,4],[3,2,1]]

zip(board1, board2):[([1, 2, 3], [9, 8, 7]), ([4, 5, 6], [6, 5, 4]), ([7, 8, 9], [3, 2, 1])]

zip将两个可迭代的(tumple, list, set, dict)上下对比粘合到一起

 

board1=[[1,2,3],[4,5,6],[7,8,9]]

zip(*board),可实现上下匹配,即(147),(258),(369),正是我要的列向量。

zip(board),仅仅是变成元组,即(123),(456),(789)

 

今后再写代码刷题,不单要实现功能和优化算法,更要让程序看起来很美,美=可读性+简洁。OK继续加油!

 

posted @ 2015-10-30 18:13  面包包包包包包  阅读(679)  评论(0编辑  收藏  举报