01.02.03 练习题目(第 04 天)
1. 0048. 旋转图像
1.1 题目大意
描述:给定一个 n × n n \times n n×n 大小的二维矩阵(代表图像) m a t r i x matrix matrix。
要求:将二维矩阵 m a t r i x matrix matrix 顺时针旋转 90°。
说明:
- 不能使用额外的数组空间。
- n = = m a t r i x . l e n g t h = = m a t r i x [ i ] . l e n g t h n == matrix.length == matrix[i].length n==matrix.length==matrix[i].length。
- 1 ≤ n ≤ 20 1 \le n \le 20 1≤n≤20。
- − 1000 ≤ m a t r i x [ i ] [ j ] ≤ 1000 -1000 \le matrix[i][j] \le 1000 −1000≤matrix[i][j]≤1000。
示例:
- 示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[[7,4,1],[8,5,2],[9,6,3]]
- 示例 2:
解题思路:
我们可以发现轮转后的数组是把原来的四个数组按照下标重新组成了新的四个数组,按照下下标重新组成数组,我们不难想到zip()函数。而后我们发现15 13 2 5的顺序变成了倒序,我们可以选择在新数组中变成倒叙,或者在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[:]= list(zip(*matrix[::-1]))
# 只需一行,python的优雅
输入: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]]
2. 0054. 螺旋矩阵
2.1 题目大意
描述:给定一个 m × n m \times n m×n 大小的二维矩阵 m a t r i x matrix matrix。
要求:按照顺时针旋转的顺序,返回矩阵中的所有元素。
说明:
- m = = m a t r i x . l e n g t h m == matrix.length m==matrix.length。
- n = = m a t r i x [ i ] . l e n g t h n == matrix[i].length n==matrix[i].length。
- 1 ≤ m , n ≤ 10 1 \le m, n \le 10 1≤m,n≤10。
- − 100 ≤ m a t r i x [ i ] [ j ] ≤ 100 -100 \le matrix[i][j] \le 100 −100≤matrix[i][j]≤100。
示例:
- 示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
- 示例 2:
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]
解题思路:
在该题中我们可以借鉴上一题的思路,因为我们要获得这些元素的顺序,可以不断的进行旋转。所以就是弹出list[0],然后进行旋转,再弹直至列表为空
我的题解
class Solution(object):
def spiralOrder(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: List[int]
"""
res = []
while(matrix):
res += matrix.pop(0)
matrix[:] = list(zip(*matrix[:]))[::-1]
return res
3. 0498. 对角线遍历
3.1 题目大意
描述:给定一个大小为 m × n m \times n m×n 的矩阵 m a t mat mat 。
要求:以对角线遍历的顺序,用一个数组返回这个矩阵中的所有元素。
说明:
- m = = m a t . l e n g t h m == mat.length m==mat.length。
- n = = m a t [ i ] . l e n g t h n == mat[i].length n==mat[i].length。
- 1 ≤ m , n ≤ 1 0 4 1 \le m, n \le 10^4 1≤m,n≤104。
- 1 ≤ m × n ≤ 1 0 4 1 \le m \times n \le 10^4 1≤m×n≤104。
- − 1 0 5 ≤ m a t [ i ] [ j ] ≤ 1 0 5 -10^5 \le mat[i][j] \le 10^5 −105≤mat[i][j]≤105。
示例:
- 示例 1:
输入:mat = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,4,7,5,3,6,8,9]
- 示例 2:
输入:mat = [[1,2],[3,4]]
输出:[1,2,3,4]
解题思路:
在该题中我们可以先尝试举几个例子,发现一些规律。
比如:
- 遍历的次数n = x(行数) + y(列数) - 1
- 遍历时满足(x == y时): s u m ( x i , y i ) = n sum(x_i,y_i) = n sum(xi,yi)=n
- 当n为偶数到边界时, y i + 1 y_i + 1 yi+1;n为奇数时, x i + 1 x_i + 1 xi+1
需要提到的是第二条的条件,当 x != y 时,我们需要控制边界我们要取 m i n ( x i , n ) 和 m i n ( y i , n ) min(x_i, n)和min(y_i, n) min(xi,n)和min(yi,n)同时,在实现过程中当m != n 时也会出现超出下边界的问题,所以也需要用到max()
我的题解
class Solution(object):
def findDiagonalOrder(self, mat):
"""
:type mat: List[List[int]]
:rtype: List[int]
"""
res = []
m, n, times = len(mat) ,len(mat[0]) ,len(mat) + len(mat[0]) - 1
for i in range(times):
if i % 2:
for k in range(max(0, i - n + 1), min(i + 1, m)): res.append(mat[k][i - k])
else:
for k in range(min(m - 1, i), max(-1, i - n), -1): res.append(mat[k][i - k])
return res