Array 类题目选做之二 二维矩阵
54. Spiral Matrix
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
Example 1:
Input:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
Output: [1,2,3,6,9,8,7,4,5]
解析:该题仍然没有用到什么复杂的算法,关键是找规律。旋转一圈为一轮,控制每轮的起始位置和顺序即可。对于最后剩下一行或一列进行了特殊处理,想必也有优化办法。代码如下:
class Solution:
def spiralOrder(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: List[int]
"""
res = []
if not matrix or not matrix[0]:
return res
i_sta, j_sta = 0, 0
i_end = len(matrix) - 1
j_end = len(matrix[0]) - 1
while i_sta < i_end and j_sta < j_end :
i = i_sta
for j in range(j_sta, j_end):
res.append(matrix[i][j])
j = j_end
for i in range(i_sta, i_end):
res.append(matrix[i][j])
i = i_end
for j in range(j_end, j_sta, -1):
res.append(matrix[i][j])
j = j_sta
for i in range(i_end, i_sta, -1):
res.append(matrix[i][j])
i_sta += 1
i_end -= 1
j_sta += 1
j_end -= 1
if i_sta == i_end and j_sta == j_end:
res.append(matrix[i_sta][j_sta])
elif i_sta == i_end:
res.extend(matrix[i_sta][j_sta:j_end+1])
elif j_sta == j_end:
for i in range(i_sta, i_end+1):
res.append(matrix[i][j_sta])
return res
相比之下,59题Given a positive integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. 方阵的问题就更容易了。
48. Rotate Image
You are given an n x n 2D matrix representing an image.
Rotate the image by 90 degrees (clockwise).
Note:
You have to rotate the image in-place, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation.
Example 1:
Given input matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
rotate the input matrix in-place such that it becomes:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
解析:这一题是要求原位旋转方阵,O(1)空间的,有了上一题的基础,旋转的基本写法应该熟悉了。看如下代码,先循环控制轮次,再存储一个变量,按逆时针顺序转过去,每次转中心对称的一个位置的四个数。
class Solution:
def rotate(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: void Do not return anything, modify matrix in-place instead.
"""
l = len(matrix)
if l < 2:
return
sta, end = 0, l-1
while sta < end:
cp = 0
for i in range(sta, end):
cp = matrix[sta][i]
matrix[sta][i] = matrix[l-1-i][sta]
matrix[l-1-i][sta] = matrix[end][l-1-i]
matrix[end][l-1-i] = matrix[i][end]
matrix[i][end] = cp
sta += 1
end -= 1
return
73. Set Matrix Zeroes
Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place.
Example 1:
Input:
[
[1,1,1],
[1,0,1],
[1,1,1]
]
Output:
[
[1,0,1],
[0,0,0],
[1,0,1]
]
解析:仍然是处理二维数组,但不是旋转了。记录需要置0的行列即可,那么写出来一定是O(m+n)space的,难点在于O(1)空间复杂度的算法。像上一节一维数组的问题,如果用O(1)space 那么肯定是要在原地记录和调整(原地交换)。看如下代码,用每行及每列首个元素记录是否需要置0,再用两个变量记录首行及首列自身是否有0。
class Solution:
def setZeroes(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: void Do not return anything, modify matrix in-place instead.
"""
if not matrix:
return
row0, col0 = 0, 0
m, n = len(matrix), len(matrix[0])
if matrix[0][0] == 0:
row0, col0 = 1, 1
for i in range(m):
if matrix[i][0] == 0:
row0 = 1
for j in range(1, n):
if i == 0 and matrix[i][j] == 0:
col0 = 1
if i != 0 and matrix[i][j] == 0:
matrix[i][0] = 0
matrix[0][j] = 0
for i in range(m-1, 0, -1):
if matrix[i][0] == 0:
for j in range(1,n):
matrix[i][j] = 0
for i in range(n-1, 0, -1):
if matrix[0][i] == 0:
for j in range(1,m):
matrix[j][i] = 0
if row0 == 1:
for i in range(m):
matrix[i][0] = 0
if col0 == 1:
for j in range(n):
matrix[0][j] = 0