59. Spiral Matrix II
https://leetcode.com/problems/spiral-matrix-ii/
solution
循环不变量,矩阵四条边都使用同一种左闭右开或左闭右闭的形式。新建一个数组用于更新数据,不必in-place
以下采用了左闭右闭的形式
# value递进,坐标变换: https://algo.monster/liteproblems/59
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
row_start, row_end = 0, n - 1
col_start, col_end = 0, n - 1
num = 1
res = [[0 for _ in range(n)] for _ in range(n)]
while row_end >= row_start and col_end >= col_start:
for i in range(col_start, col_end + 1):
res[row_start][i] = num
num += 1
row_start += 1
for i in range(row_start, row_end + 1):
res[i][col_end] = num
num += 1
col_end -= 1
for i in range(col_end, col_start - 1, -1):
res[row_end][i] = num
num += 1
row_end -= 1
for i in range(row_end, row_start - 1, -1):
res[i][col_start] = num
num += 1
col_start += 1
return res
时间复杂度:O(n^2) 空间复杂度:O(1)
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
matrix = [[0] * n for _ in range(n)]
dirs = [[0, 1], [1, 0], [0, -1], [-1, 0]]
row = col = 0
dir_idx = 0
for value in range(1, 1 + n*n):
matrix[row][col] = value
next_row = row + dirs[dir_idx][0]
next_col = col + dirs[dir_idx][1]
if next_row < 0 or next_row >= n or next_col < 0 or next_col >= n or matrix[next_row][next_col]:
dir_idx = (dir_idx + 1) % 4
next_row = row + dirs[dir_idx][0]
next_col = col + dirs[dir_idx][1]
row, col = next_row, next_col
return matrix
follow up
# 一直取第一行,取完之后进行逆时针旋转
class Solution:
def printMatrix(self, matrix):
result = []
while(matrix):
result += matrix.pop(0)
if not matrix or not matrix[0]:
break
matrix = self.turn(matrix)
return result
def turn(self,matrix):
num_r = len(matrix)
num_c = len(matrix[0])
new_mat = []
for i in range(num_c-1, -1, -1):
new_mat2 = []
for j in range(num_r):
new_mat2.append(matrix[j][i])
new_mat.append(new_mat2)
return new_mat
时间复杂度:O() 空间复杂度:O()
行先倒过来,两两替换元素。注意控制index避免重复
class Solution:
def rotate(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
matrix.reverse() # 注意inplace, 用matrix=matrix[::-1]不对
for i in range(len(matrix)):
for j in range(i, len(matrix)):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
时间复杂度:O(n^2) 空间复杂度:O(1)
模拟,每次到首或尾就转换方向,模拟题需要耐心的想一想
class Solution:
def convert(self, s: str, numRows: int) -> str:
if numRows == 1:
return s
rows = [''] * numRows
k = 0
direction = - 1
for c in s:
rows[k] += c
if k == 0 or k == numRows - 1:
direction *= -1
k += direction
return ''.join(rows)
时间复杂度:O() 空间复杂度:O()
# direct_index的做法根据index增量也不错:https://algo.monster/liteproblems/54
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
m = len(matrix)
n = len(matrix[0])
res = []
i_start = 0
i_end = m - 1
j_start = 0
j_end = n - 1
while i_start <= i_end and j_start <= j_end:
for j in range(j_start, j_end+1):
res.append(matrix[i_start][j])
i_start += 1
for i in range(i_start, i_end+1):
res.append(matrix[i][j_end])
j_end -= 1
for j in range(j_end, j_start-1, -1):
res.append(matrix[i_end][j])
i_end -= 1
for i in range(i_end, i_start-1, -1):
res.append(matrix[i][j_start])
j_start += 1
return res[:m*n] # 注意最后的处理
根据同一level, 行加列的index和相同
class Solution:
def findDiagonalOrder(self, mat: List[List[int]]) -> List[int]:
counter = collections.defaultdict(list)
m = len(mat)
n = len(mat[0])
for i in range(m):
for j in range(n):
counter[i+j].append(mat[i][j])
res = []
for x in range(m + n - 1):
x_list = counter[x]
if x % 2 == 0:
x_list.reverse()
res += x_list
return res
class Solution:
def findDiagonalOrder(self, nums: List[List[int]]) -> List[int]:
res = collections.defaultdict(list)
for i in range(len(nums)):
for j in range(len(nums[i])):
res[i + j].append(nums[i][j])
res_list = [i[::-1] for i in res.values()]
return sum(res_list, []) # 拉平
Last updated