Leetcode 73:矩陣置零(最詳細的解法!!!)
阿新 • • 發佈:2018-12-17
給定一個 m x n 的矩陣,如果一個元素為 0,則將其所在行和列的所有元素都設為 0。請使用原地演算法**。**
示例 1:
輸入:
[
[1,1,1],
[1,0,1],
[1,1,1]
]
輸出:
[
[1,0,1],
[0,0,0],
[1,0,1]
]
示例 2:
輸入:
[
[0,1,2,0],
[3,4,5,2],
[1,3,1,5]
]
輸出:
[
[0,0,0,0],
[0,4,5,0],
[0,3,1,0]
]
進階:
- 一個直接的解決方案是使用 O(m**n) 的額外空間,但這並不是一個好的解決方案。
- 一個簡單的改進方案是使用 O(m + n) 的額外空間,但這仍然不是最好的解決方案。
- 你能想出一個常數空間的解決方案嗎?
解題思路
一個最簡答的思路就是通過遍歷矩陣的每一個元素,判斷這個元素是不是0
,如果是的話那麼將對應的行和列的元素置為零,但是這種有一個陷阱,因為一旦置為零,那麼我們對於沒有遍歷到的元素就會存在這樣的風險:原先不是0
,但是因為之前有數將其置為0
了,我們遍歷到這個原本是非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
r, c = len(matrix), len(matrix[0])
mat = [[0]*c for _ in range(r)]
for i in range(r):
for j in range(c):
mat[i][j] = matrix[i][j]
for i in range(r):
for j in range(c):
if mat[i][j] == 0:
for m in range(r):
matrix[m][j] = 0
for n in range(c):
matrix[i][n] = 0
有沒有更好的做法呢?就像進階中提到的,我們是不是有空間複雜度更小的做法。我們可以這樣考慮,例如
0 |1 1 2
3 |1 5 2
0 |3 0 5
對於第一列元素我們單獨考慮。當我們碰到0
,也就是2,2
這個點,所以我們將之前的同一行同一列的第一行和第一列置為0
0 1 0 2
3 1 5 2
0 3 0 5
接著我們根據第一行和第一列的0
和非0
將矩陣的(除了第一行第一列)行和列全置為0
0 1 0 2
|-------
3 |1 0 2
0 |0 0 0
我們接著要考慮第一行和第一列的問題,如果0,0
對應元素是0
,我們將第一行置為0
。
0 0 0 0
3 1 0 2
0 0 0 0
接著我們考慮第一列的問題,什麼時候該考慮它呢?如果在上述操作之前第一列存在0
的話,我們將第一列全置為0
0 0 0 0
0 1 0 2
0 0 0 0
我們通過這個演算法,就可以使用O(1)
的空間複雜度解決這個問題。
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
r, c, flag = len(matrix), len(matrix[0]), False
for i in range(r):
if matrix[i][0] == 0:
flag = True
for j in range(1, c):
if matrix[i][j] == 0:
matrix[0][j] = 0
matrix[i][0] = 0
for i in range(1, r):
for j in range(1, c):
if not matrix[i][0] or not matrix[0][j]:
matrix[i][j] = 0
if matrix[0][0] == 0:
for j in range(c):
matrix[0][j] = 0
if flag:
for i in range(r):
matrix[i][0] = 0
如有問題,希望大家指出!!!