-
Notifications
You must be signed in to change notification settings - Fork 4
/
Matrix.py
executable file
·293 lines (271 loc) · 10.2 KB
/
Matrix.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
File Name: Matrix
Description :
Author : amilyxy
date: 2019/9/23
-------------------------------------------------
"""
'''
63. Rotate Image: 旋转图像
describe: 给定一个 n × n 的二维矩阵表示一个图像,将图像顺时针旋转90度
必须原地旋转矩阵
'''
import math
class Solution:
# 我的思路: 从外而内对矩每个值进行旋转
def rotate(self, matrix: list[list[int]]) -> None:
n = len(matrix[0])-1
ring = math.ceil(len(matrix[0])/2)
for i in range(ring):
# 列
col = i
for j in range(i, n-i):
# 行
row = j
temp = matrix[row][col]
for z in range(4):
# 下一个值给temp
row1 = col
col1 = (n - row)
temp1 = matrix[row1][col1]
matrix[row1][col1] = temp
col = col1
row = row1
temp = temp1
# 上面可以改成(多利用多元赋值!!
# row1, col1 = col, (n - row)
# matrix[row1][col1], temp = temp, matrix[row1][col1]
# row, col = row1, col1
# 题解方法 转置加翻转(我怎么就没观察出这个规律呢!!
def rotate(self, matrix):
n = len(matrix[0])
# transpose matrix
for i in range(n):
for j in range(i, n):
# 多元赋值还是秀啊
matrix[j][i], matrix[i][j] = matrix[i][j], matrix[j][i]
# reverse each row
for i in range(n):
matrix[i].reverse()
# 题解方法 三
# 感觉这个也挺好的 将四次循环用四个多元赋值表示 比较简洁
def rotate(self, matrix):
n = len(matrix[0])
for i in range(n // 2 + n % 2):
for j in range(n // 2):
tmp = matrix[n - 1 - j][i]
matrix[n - 1 - j][i] = matrix[n - 1 - i][n - j - 1]
matrix[n - 1 - i][n - j - 1] = matrix[j][n - 1 - i]
matrix[j][n - 1 - i] = matrix[i][j]
matrix[i][j] = tmp
'''
54. Spiral Matrix: 螺旋矩阵
describe: 给定一个包含 m x n 个元素的矩阵(m 行, n 列)
请按照顺时针螺旋顺序,返回矩阵中的所有元素。
'''
class Solution:
# 题解方法就不写了
def spiralOrder(self, matrix: list[list[int]]) -> list[int]:
res = []
if len(matrix) == 0:
return res
n = len(matrix[0])
m = len(matrix)
ring = (min(m, n) + 1) // 2
for i in range(ring):
# 行
row, col = i, list(range(i, n - i))
res.extend([matrix[row][z] for z in col])
print(res)
row, col = list(range(i + 1, m - i)), col[-1]
res.extend([matrix[z][col] for z in row])
if len(row) != 0:
row, col = row[-1], list(range(n - i - 2, i - 1, -1))
res.extend([matrix[row][z] for z in col])
else:
return res
if len(col) != 0:
row, col = list(range(m - i - 2, i, -1)), col[-1]
res.extend([matrix[z][col] for z in row])
else:
return res
return res
# 题解简单方法(比较难理解
def spiralOrder(self, matrix: list[list[int]]) -> list[int]:
res = []
while matrix:
res += matrix.pop(0)
matrix = list(map(list, zip(*matrix)))[::-1]
print(matrix)
return res
# 最近做剑指offer发现的新的做法 标记数组
# 只是我觉得最一目了然的做法
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
# 标记做法
res = []
dire = [[0, 1], [1, 0], [0, -1], [-1, 0]] #方向右下左上
m = len(matrix)
if m:
n = len(matrix[0])
else:
return matrix
marked = [[0 for _ in range(n)] for _ in range(m)]
i, j, k= 0, 0, 0
while 0<=i<m and 0<=j<n and not marked[i][j]:
res.append(matrix[i][j])
marked[i][j] = 1
while 0<= i+dire[k][0] <m and 0<=j+dire[k][1]<n and not marked[i+dire[k][0]][j+dire[k][1]]:
i+=dire[k][0]
j+=dire[k][1]
res.append(matrix[i][j])
marked[i][j] = 1
k = (k+1)%4
i = i+dire[k][0]
j = j+dire[k][1]
return res
'''
59. Spiral Matrix: 螺旋矩阵II
describe: 给定一个正整数 n,生成一个包含 1 到 n2 所有元素
且元素按顺时针顺序螺旋排列的正方形矩阵。
'''
class Solution:
def generateMatrix(self, n: int) -> list[list[int]]:
res = list(range(1, n * n + 1))
matrix = [[0 for i in range(n)] for j in range(n)]
ring = (n + 1) // 2
for i in range(ring):
# 行
row, col = i, list(range(i, n - i))
for z in col:
matrix[row][z] = res[0]
res.pop(0)
row, col = list(range(i + 1, n - i)), col[-1]
for z in row:
matrix[z][col] = res[0]
res.pop(0)
if len(row) != 0:
row, col = row[-1], list(range(n - i - 2, i - 1, -1))
for z in col:
matrix[row][z] = res[0]
res.pop(0)
else:
return matrix
if len(col) != 0:
row, col = list(range(n - i - 2, i, -1)), col[-1]
for z in row:
matrix[z][col] = res[0]
res.pop(0)
else:
return matrix
return matrix
# 方法二
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
dire = [[0, 1], [1, 0], [0, -1], [-1, 0]] #方向右下左上
marked = [[0 for _ in range(n)] for _ in range(n)]
i, j, k, count = 0, 0, 0, 1
while 0<=i<n and 0<=j<n and not marked[i][j]:
marked[i][j] = count
count += 1
while 0<= i+dire[k][0] <n and 0<=j+dire[k][1]<n and not marked[i+dire[k][0]][j+dire[k][1]]:
i+=dire[k][0]
j+=dire[k][1]
marked[i][j] = count
count += 1
k = (k+1)%4
i = i+dire[k][0]
j = j+dire[k][1]
return marked
'''
73. Set Matrix Zeroes 矩阵置零
'''
# m+n的来了 好吧 看了一圈好像我写的这个是最复杂的 需要额外的存储空间
class Solution:
def setZeroes(self, matrix: list[list[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
m = len(matrix)
n = len(matrix[0])
setzeroi = set()
setzeroj = set()
for i in range(m):
for j in range(n):
if matrix[i][j] == 0:
setzeroi.add(i)
setzeroj.add(j)
for i in range(m):
for j in range(n):
if i in setzeroi or j in setzeroj:
matrix[i][j] = 0
# O(1)的作法 @powcai(好强
class Solution(object):
def setZeroes(self, matrix):
is_col = False
R = len(matrix)
C = len(matrix[0])
for i in range(R):
if matrix[i][0] == 0: is_col = True
for j in range(1, C):
if matrix[i][j] == 0:
matrix[0][j] = 0
matrix[i][0] = 0
for i in range(R-1,-1,-1):
for j in range(C-1,0,-1):
if not matrix[i][0] or not matrix[0][j]:
matrix[i][j] = 0
if is_col: matrix[i][0] = 0
'''
329. Longest Increasing Path in a Matrix 矩阵中的最长递增路径
'''
# 写了好久终于写出来了 运行时间有点长 804ms
# 看到答案有先排序在搜索的方法 确实挺巧妙的 我的方法还可以照这个再改进
class Solution:
def longestIncreasingPath(self, matrix: list[list[int]]) -> int:
m = len(matrix)
if m == 0:
return 0
else:
n = len(matrix[0])
dire = [(-1, 0), (1, 0), (0, -1), (0, 1)]
maxlen = [[-1 for _ in range(n)] for _ in range(m)] # 矩阵中每个值都是都是其最长递增路径
def helper(i, j):
temp = [0]
for k in dire:
newi, newj = i + k[0], j + k[1]
if 0 <= newi < m and 0 <= newj < n and matrix[newi][newj] > matrix[i][j]:
if maxlen[newi][newj] != -1:
temp.append(1 + maxlen[newi][newj])
else:
temp.append(1 + helper(newi, newj))
maxlen[i][j] = max(temp)
return max(temp)
for i in range(m):
for j in range(n):
if maxlen[i][j] == -1:
maxlen[i][j] = helper(i, j)
print(maxlen)
return max(max(row) for row in maxlen) + 1
# 评论里面与众不同的一个方法 加了排序步骤
class Solution(object):
def longestIncreasingPath(self, matrix):
if not matrix or not matrix[0]:
return 0
m, n = len(matrix), len(matrix[0])
lst = []
for i in range(m):
for j in range(n):
lst.append((matrix[i][j], i, j))
lst.sort()
dp = [[0 for _ in range(n)] for _ in range(m)]
for num, i, j in lst:
dp[i][j] = 1
for di, dj in [(0, 1), (1, 0), (0, -1), (-1, 0)]:
r, c = i + di, j + dj
if 0 <= r < m and 0 <= c < n:
if matrix[i][j] > matrix[r][c]:
dp[i][j] = max(dp[i][j], 1 + dp[r][c])
return max([dp[i][j] for i in range(m) for j in range(n)])