判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。
示例 1:
输入:
[[“5”,“3”,".",".",“7”,".",".",".","."],
[“6”,".",".",“1”,“9”,“5”,".",".","."],
[".",“9”,“8”,".",".",".",".",“6”,"."],
[“8”,".",".",".",“6”,".",".",".",“3”],
[“4”,".",".",“8”,".",“3”,".",".",“1”],
[“7”,".",".",".",“2”,".",".",".",“6”],
[".",“6”,".",".",".",".",“2”,“8”,"."],
[".",".",".",“4”,“1”,“9”,".",".",“5”],
[".",".",".",".",“8”,".",".",“7”,“9”]]
输出: true
示例 2:
输入:
[[“8”,“3”,".",".",“7”,".",".",".","."],
[“6”,".",".",“1”,“9”,“5”,".",".","."],
[".",“9”,“8”,".",".",".",".",“6”,"."],
[“8”,".",".",".",“6”,".",".",".",“3”],
[“4”,".",".",“8”,".",“3”,".",".",“1”],
[“7”,".",".",".",“2”,".",".",".",“6”],
[".",“6”,".",".",".",".",“2”,“8”,"."],
[".",".",".",“4”,“1”,“9”,".",".",“5”],
[".",".",".",".",“8”,".",".",“7”,“9”]]
输出: false
解释: 除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。
—————————————————————————————————————————
class Solution:
def isValidSudoku(self, board):
"""
:type board: List[List[str]]
:rtype: bool
"""
# 行中没有重复的数字
for i in range(9):
rows = []
for j in range(9):
if board[i][j] in rows:
return False
if board[i][j] != ".":
rows.append(board[i][j])
# 列中没有重复的数字
for j in range(9):
columns = []
temp = [x[j] for x in board]
for d in temp:
if d in columns:
return False
if d != ".":
columns.append(d)
# 3 x 3 子数独内没有重复的数字
subs = [[] for i in range(9)]
for row in range(9):
for column in range(9):
box_index = (row // 3) * 3 + column // 3
if board[row][column] != ".":
subs[box_index].append(board[row][column])
for k in subs:
if len(k) != len(set(k)):
return False
return True
在行列遍历时,我本想通过以下方法来快速完成,但是board是存储多个行list的表,所以在列查找时,下面方法不可以使用,放到下面来提醒自己:
for i in range(9):
for j in range(1,10):
if board[i][:].count(j) > 1 or board[:][i].count(j) > 1:
return False
else:
continue
还有此行代码是因为将每一个3x3通过行列的规律变为box_index不同的9块,非常巧妙。
box_index = (row // 3) * 3 + column // 3
很新颖的思路,尤其是最后一次遍历
class Solution:
def isSingle(self,l):
d = {}
for i in l:
if i != '.':
if i in d:
return False
else:
d[i] = 1
else:
continue
return True
def isValidSudoku(self, board):
"""
:type board: List[List[str]]
:rtype: bool
"""
for l in board:
if not self.isSingle(l):
return False
else:
continue
for i in range(9):
l = [x[i] for x in board]
if not self.isSingle(l):
return False
else:
continue
for i in (0,3,6):
for j in (0,3,6):
l = board[j][i:i + 3] + board[j + 1][i:i + 3] + board[j + 2][i:i + 3]
if not self.isSingle(l):
return False
return True
将[行,值],[列,值],[3x3内,值]作为输出,最后看有无重叠部分。
class Solution(object):
def isValidSudoku(self, board):
"""
:type board: List[List[str]]
:rtype: bool
"""
seen = sum(([(c, i), (j, c), (i/3, j/3, c)]
for i, row in enumerate(board)
for j, c in enumerate(row)
if c != '.'), [])
return len(seen) == len(set(seen))
惊为天人,每当有行或列有两值相同时,在最后的seen输出时会被set删掉重复值。
小tip:sum()函数
其中后面的[]是sum函数内的初始值,当初始值设为[]时,输出就是将所有情况排列了:
输入:
[[“5”,“3”,".",".",“7”,".",".",".","."],
[“6”,".",".",“1”,“9”,“5”,".",".","."],
[".",“9”,“8”,".",".",".",".",“6”,"."],
[“8”,".",".",".",“6”,".",".",".",“3”],
[“4”,".",".",“8”,".",“3”,".",".",“1”],
[“7”,".",".",".",“2”,".",".",".",“6”],
[".",“6”,".",".",".",".",“2”,“8”,"."],
[".",".",".",“4”,“1”,“9”,".",".",“5”],
[".",".",".",".",“8”,".",".",“7”,“9”]]
seen输出:
[[“5”,0],[0,“5”],[0,0,“5”],[“3”,0],[1,“3”],[0,0,“3”],[“7”,0],[4,“7”],[0,1,“7”],[“6”,1],[0,“6”],[0,0,“6”],[“1”,1],[3,“1”],[0,1,“1”],[“9”,1],[4,“9”],[0,1,“9”],[“5”,1],[5,“5”],[0,1,“5”],[“9”,2],[1,“9”],[0,0,“9”],[“8”,2],[2,“8”],[0,0,“8”],[“6”,2],[7,“6”],[0,2,“6”],[“8”,3],[0,“8”],[1,0,“8”],[“6”,3],[4,“6”],[1,1,“6”],[“3”,3],[8,“3”],[1,2,“3”],[“4”,4],[0,“4”],[1,0,“4”],[“8”,4],[3,“8”],[1,1,“8”],[“3”,4],[5,“3”],[1,1,“3”],[“1”,4],[8,“1”],[1,2,“1”],[“7”,5],[0,“7”],[1,0,“7”],[“2”,5],[4,“2”],[1,1,“2”],[“6”,5],[8,“6”],[1,2,“6”],[“6”,6],[1,“6”],[2,0,“6”],[“2”,6],[6,“2”],[2,2,“2”],[“8”,6],[7,“8”],[2,2,“8”],[“4”,7],[3,“4”],[2,1,“4”],[“1”,7],[4,“1”],[2,1,“1”],[“9”,7],[5,“9”],[2,1,“9”],[“5”,7],[8,“5”],[2,2,“5”],[“8”,8],[4,“8”],[2,1,“8”],[“7”,8],[7,“7”],[2,2,“7”],[“9”,8],[8,“9”],[2,2,“9”]]
给定一个 n × n 的二维矩阵表示一个图像。
将图像顺时针旋转 90 度。
说明:
你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。
示例 1:
给定 matrix =
[[1,2,3],
[4,5,6],
[7,8,9]],
原地旋转输入矩阵,使其变为:
[[7,4,1],
[8,5,2],
[9,6,3]]
示例 2:
给定 matrix =
[[ 5, 1, 9,11],
[ 2, 4, 8,10],
[13, 3, 6, 7],
[15,14,12,16]],
原地旋转输入矩阵,使其变为:
[[15,13, 2, 5],
[14, 3, 4, 1],
[12, 6, 8, 9],
[16, 7,10,11]]
—————————————————————————————————————————
class Solution(object):
def rotate(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: None Do not return anything, modify matrix in-place instead.
"""
for i in range(len(matrix)):
for j in range(i):
matrix[i][j],matrix[j][i] = matrix[j][i],matrix[i][j]
for i in range(len(matrix)):
matrix[i] = matrix[i][::-1]
class Solution(object):
def rotate(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: None Do not return anything, modify matrix in-place instead.
"""
matrix[:] = matrix[::-1]
for i in range(len(matrix)):
for j in range(i+1,len(matrix)):
matrix[i][j],matrix[j][i] = matrix[j][i],matrix[i][j]
其实上述转置与翻转可以使用python内置函数zip(*)一行代码完成
class Solution(object):
def rotate(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: None Do not return anything, modify matrix in-place instead.
"""
matrix[:] = map(list,zip(*matrix[::-1]))
其中zip()函数为压缩函数,zip([seql, …])接受一系列可迭代对象作为参数,将对象中对应的元素打包成一个个tuple(元组),然后返回由这些tuples组成的list(列表),若传入参数的长度不等,则返回list的长度和参数中长度最短的对象相同,而zip(*)可以将已经zip过的列表对象解压。这个用法可以用来实现矩阵的转置。
使用以上方法,还可以通过转置与翻转的顺序不同实现逆时针旋转,就是先进行转置再上下翻转或者先左右翻转再转置。
小tip:
以上就是今日经验!