日常系列LeetCode《3·二维数组篇》
Posted 常某某的好奇心
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了日常系列LeetCode《3·二维数组篇》相关的知识,希望对你有一定的参考价值。
数据规模->时间复杂度
<=10^4 😮(n^2)
<=10^7:o(nlogn)
<=10^8:o(n)
10^8<=:o(1)
总结:
1.索引计算:根据某个元素的行列索引计算另一个元素的行列索引
2.行走遍历:在二维数组中行走遍历
3.元素值计算:根据二维数组某些元素计算另一个元素值
lc 867:https://leetcode.cn/problems/transpose-matrix/
提示:
m = =matrix.length
n = =matrix[i].length
1 <= m, n <= 1000
1 <= m * n <= 10^5
-10^9 <= matrix[i][j] <= 10^9
class Solution:
def transpose(self, matrix: List[List[int]]) -> List[List[int]]:
#o(m*n)
m,n=len(matrix),len(matrix[0])
t=[[0]*m for i in range(n)]
#
for i in range(m):
for j in range(n):
t[j][i]=matrix[i][j]
#
return t
lc 48 【top100】:https://leetcode.cn/problems/rotate-image/
提示:
n = = matrix.length = = matrix[i].length
1 <= n <= 20
-1000 <= matrix[i][j] <= 1000
方案一(不满足):使用额外数组(o(n^2),o(n^2))
#对于矩阵中第row行的第col列元素,在旋转后,它出现在倒数第row列的第col行位置。
方案二:原地旋转
class Solution:
def rotate(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
#o(1)
n=len(matrix)
#o(n^2)
for i in range(n//2): #取整3.5-3,4.0-4.5
for j in range((n+1)//2):
#留空
tmp=matrix[i][j]
#
matrix[i][j]=matrix[n-1-j][i]
matrix[n-1-j][i]=matrix[n-1-i][n-1-j]
matrix[n-1-i][n-1-j]=matrix[j][n-1-i]
matrix[j][n-1-i]=tmp
#
return matrix
方案三:原地翻转:水平翻转->主对角线翻转
class Solution:
def rotate(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
#o(1)
n=len(matrix)
#o(n^2)
#水平交换
for i in range(n//2):
for j in range(n):
matrix[i][j],matrix[n-1-i][j]=matrix[n-1-i][j], matrix[i][j]
#主对角线转置
for i in range(n):
for j in range(i):
matrix[i][j],matrix[j][i]=matrix[j][i], matrix[i][j]
#
return matrix
lc 36:https://leetcode.cn/problems/valid-sudoku/
提示:
board.length = = 9
board[i].length == 9
board[i][j] 是一位数字(1-9)或者 ‘.’
#rowUsed[row][num] = true:在数字num + 1在row行已经存在
#colUsed[col][num] = true:在数字num + 1在col行已经存在
#boxUsed[boxIndex][num] = true:在数字num + 1在boxIndex个箱子已经存在
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
#o(n)
rowused=[[False]*9 for _ in range(9)]
colused=[[False]*9 for _ in range(9)]
boxused=[[False]*9 for _ in range(9)]
#o(n^2)
for i in range(9):
for j in range(9):
if board[i][j]!='.':
num=ord(board[i][j])-ord('1')
#
if rowused[i][num]:return False
else:rowused[i][num]=True
if colused[j][num]:return False
else:colused[j][num]=True
if boxused[(i//3+(j//3)*3)][num]:return False
else:boxused[(i//3+(j//3)*3)][num]=True
#
return True
lc 73 :https://leetcode.cn/problems/set-matrix-zeroes/
提示:
m = = matrix.length
n == matrix[0].length
1 <= m, n <= 200
-2^31 <= matrix[i][j] <= 2^31 - 1
进阶:
一个直观的解决方案是使用 O(mn) 的额外空间,但这并不是一个好的解决方案。
一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。
你能想出一个仅使用常量空间的解决方案吗?
#方案一:o(m*n):一个矩阵
#方案二:o(m+n):两个数组
#记录每行是否需要置为О;记录每列是否需要置为0
class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
#o(m+n)
rows=[False]*len(matrix)
cols=[False]*len(matrix[0])
#o(m*n)
#标记
for i in range(len(matrix)):
for j in range(len(matrix[0])):
if matrix[i][j]==0:
rows[i]=True
cols[j]=True
#设0
for i in range(len(matrix)):
for j in range(len(matrix[0])):
if rows[i] or cols[j]:
matrix[i][j]=0
#
return matrix
#方案三:o(1):单数组
#核心:'第一列是否含0'作为整体标记,方便了处本列之外信息的设0
#注:为了防止每一列的第一个元素被提前更新,我们需要从最后一行开始,倒序地处理矩阵元素
class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
#o(1)
m=len(matrix)
n=len(matrix[0])
#o(n)
#标记
col1=False
for i in range(m):
if matrix[i][0]==0:#第一列(是否含0)
col1=True
for j in range(1,n):
if matrix[i][j]==0:#其他行、列(含0信息)
matrix[i][0]=matrix[0][j]=0
#设0
for i in range(m-1,-1,-1): #注:逆序
for j in range(1,n):
if matrix[i][0]==0 or matrix[0][j]==0:
matrix[i][j]=0
if col1:#注:放最后
matrix[i][0]=0
#
return matrix
#核心:'第一行是否含0'作为整体标记,方便了处本行之外信息的设0
#注:为了防止每一行的第一个元素被提前更新,我们需要从最后一列开始,倒序地处理矩阵元素
class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
#o(1)
m=len(matrix)
n=len(matrix[0])
#o(n)
#标记
row1=False
for j in range(n):
if matrix[0][j]==0:#第一行(是否含0)
row1=True
for i in range(1,m):
for j in range(n):
if matrix[i][j]==0:#其他行、列(含0信息)
matrix[i][0]=matrix[0][j]=0
#设0
for i in range(1,m):
for j in range(n-1,-1,-1):#注:逆序
if matrix[i][0]==0 or matrix[0][j]==0:
matrix[i][j]=0
for j in range(n):
if row1:#注:放最后
matrix[0][j]=0
#
return matrix
lc 54 【 剑指 29】:https://leetcode.cn/problems/spiral-matrix/
提示:
m = = matrix.length
n == matrix[i].length
1 <= m, n <= 10
-100 <= matrix[i][j] <= 100
#方案一:直接模拟
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
#o(m*n)
m,n=len(matrix),len(matrix[0])
dirs=[[0,1],[1,0],[0,-1],[-1,0]]
seen=[[False]*n for _ in range(m)] #m行n列
res=[]
#o(m*n)
i,j=0,0
di=0
for s in range(m*n):
res.append(matrix[i][j])
seen[i][j]=True
#变换条件
next_i=i+dirs[di][0]
next_j=j+dirs[di][1]
if next_i<0 or next_i>=m or next_j<0 or next_j>=n or seen[next_i][next_j]:
di=(di+1)%4 #注
#更新
i=i+dirs[di][0]
j=j+dirs[di][1]
#
return res
#方案二:按层模拟
#o(1)
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
start_row=start_col=0
end_row,end_col=len(matrix)-1,len(matrix[0])-1 #注意写法
res=[]
#o(m*n)
#注意下标
while start_row<=end_row and start_col<=end_col:
for col in range(start_col,end_col+1):res.append(matrix[start_row][col])
for row in range(start_row+1,end_row+1):res.append(matrix[row][end_col])
#注:边界(单行、单列)
if start_row<end_row and start_col<end_col:
for col in range(end_col-1,start_col,-1):res.append(matrix[end_row][col])
for row in range(end_row,start_row,-1):res.append(matrix[row][start_col])
#
start_col+=1
start_row+=1
end_col-=1
end_row-=1
return res
lc 59 :https://leetcode.cn/problems/spiral-matrix-ii/
提示:
1 <= n <= 20
#方案一:直接模拟
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
#o(1)
dirs=[[0,1],[1,0],[0,-1],[-1,0]]
seen=[[False]*n for _ in range(n)]
res=[[0]*n for _ in range(n)]
#o(m*n)
i,j=0,0
di=0
for s in range(n*n):
res[i][j]= s+1
seen[i][j]=True
#变换条件
next_i=i+dirs[di][0]
next_j=j+dirs[di][1]
if next_i<0 or next_i>=n or next_j<0 or next_j>=n or seen[next_i][next_j]:
di=(di+1)%4 #注
#更新
i=i+dirs[di][0]
j=j+dirs[di][1]
#
return res
#方案二:按层模拟
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
#o(1)
start_row=start_col=0
end_row,end_col=n-1,n-1 #注意写法
res=[[0]*n for _ in range(n)]
#o(m*n)
#注意下标
i=0
while start_row<=end_row and start_col<=end_col:
for col in range(start_col,end_col+1):
res[start_row][col]=i+1
i+=1
for row in range(start_row+1,end_row+1):
res[row][end_col]=i+1
i以上是关于日常系列LeetCode《3·二维数组篇》的主要内容,如果未能解决你的问题,请参考以下文章