給定一個 m×n 矩陣,若某元素為 0,則將其所在行和列所有元素置 0。要求原地修改,且空間複雜度 O(1)。
| 方案 | 空間 | 思路 | 缺點 |
|---|---|---|---|
| 暴力標記 | O(mn) | 複製矩陣,掃描複製件,修改原矩陣 | 空間過大 |
| 行列標記數組 | O(m+n) | 兩個布爾數組記錄哪行哪列需置零 | 仍需額外空間 |
| 首行首列作標記 | O(1) | 用矩陣第一行、第一列自身存儲標記信息 | 需額外變量記錄首行首列自身是否置零 |
firstRowZero, firstColZero 記錄。(i≥1, j≥1),若 matrix[i][j]==0,則置 matrix[i][0]=0 和 matrix[0][j]=0 作為標記。(i≥1, j≥1),若 matrix[i][0]==0 || matrix[0][j]==0 則置 matrix[i][j]=0。firstRowZero, firstColZero 決定是否將第一行、第一列置零。class Solution {
public:
void setZeroes(vector>& matrix) {
int m = matrix.size(), n = matrix[0].size();
bool firstRowZero = false, firstColZero = false;
// 1. 檢查首行首列
for (int j = 0; j < n; ++j) if (matrix[0][j] == 0) { firstRowZero = true; break; }
for (int i = 0; i < m; ++i) if (matrix[i][0] == 0) { firstColZero = true; break; }
// 2. 用首行首列標記內部元素
for (int i = 1; i < m; ++i)
for (int j = 1; j < n; ++j)
if (matrix[i][j] == 0)
matrix[i][0] = matrix[0][j] = 0;
// 3. 根據標記置零內部元素
for (int i = 1; i < m; ++i)
for (int j = 1; j < n; ++j)
if (matrix[i][0] == 0 || matrix[0][j] == 0)
matrix[i][j] = 0;
// 4. 處理首行首列
if (firstRowZero) for (int j = 0; j < n; ++j) matrix[0][j] = 0;
if (firstColZero) for (int i = 0; i < m; ++i) matrix[i][0] = 0;
}
};
1×1、1×n、m×1 矩陣均能正確處理。