原题地址:矩阵置零
给定一个 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(mn)$ 的额外空间,但这并不是一个好的解决方案。
- 一个简单的改进方案是使用 $O(m+n)$ 的额外空间,但这仍然不是最好的解决方案。
- 你能想出一个常数空间的解决方案吗?
$O(MN)$空间复杂度算法
用一个数组记录矩阵中所有的0对应的行和列,然后将这些0对应的行和列全部清0即可,具体的实现方法如下:
/**
* @param {number[][]} matrix
* @return {void} Do not return anything, modify matrix in-place instead.
*/
const setZeroes1 = function(matrix) {
if (matrix.length === 0) {
return;
}
let [m, n] = [matrix.length, matrix[0].length];
// 记录所有的0所在的行和列
let array = [];
for (let i = 0; i < m; i ++) {
for (let j = 0; j < n; j ++) {
if (matrix[i][j] === 0) {
array.push([i, j]);
}
}
}
// 对于每个0,将它的行和列全部清0
for (let item of array) {
for (let i = 0; i < n; i ++) {
matrix[item[0]][i] = 0;
}
for (let i = 0; i < m; i ++) {
matrix[i][item[1]] = 0;
}
}
};
测试:
let start = new Date();
const test = setZeroes1;
let matrix = [
[1,1,1],
[1,0,1],
[1,1,1]
];
test(matrix);
console.log(matrix); // [ [ 1, 0, 1 ], [ 0, 0, 0 ], [ 1, 0, 1 ] ]
matrix = [
[0,1,2,0],
[3,4,5,2],
[1,3,1,5]
];
test(matrix);
console.log(matrix); // [ [ 0, 0, 0, 0 ], [ 0, 4, 5, 0 ], [ 0, 3, 1, 0 ] ]
console.log(new Date().getTime() - start.getTime()); // 8
时间复杂度: 记录0所在的位置时间复杂度为$O(MN)$,清空0所在的行和列时间复杂度为$O(MN(M+N))$,所以总的时间复杂度为$O(MN(M+N+1))$
空间复杂度: 空间复杂度为$O(MN)$
$O(M+N)$空间复杂度算法
用两个数组分别记录有0存在的行和列,然后再分别将这些行和列全部清0即可,具体的实现如下:
/**
* @param {number[][]} matrix
* @return {void} Do not return anything, modify matrix in-place instead.
*/
const setZeroes2 = function(matrix) {
if (matrix.length === 0) {
return;
}
let [m, n] = [matrix.length, matrix[0].length];
// 分别记录有0存在的行和列
let [arrayM, arrayN] = [[], []];
for (let i = 0; i < m; i ++) {
for (let j = 0; j < n; j ++) {
if (matrix[i][j] === 0) {
arrayM.push(i);
break;
}
}
}
for (let i = 0; i < n; i ++) {
for (let j = 0; j < m; j ++) {
if (matrix[j][i] === 0) {
arrayN.push(i);
break;
}
}
}
// 有0存在的行列,对应行列全部清0
for (let item of arrayM) {
for (let i = 0; i < n; i ++) {
matrix[item][i] = 0;
}
}
for (let item of arrayN) {
for (let i = 0; i < m; i ++) {
matrix[i][item] = 0;
}
}
};
测试:
let start = new Date();
const test = setZeroes2;
let matrix = [
[1,1,1],
[1,0,1],
[1,1,1]
];
test(matrix);
console.log(matrix); // [ [ 1, 0, 1 ], [ 0, 0, 0 ], [ 1, 0, 1 ] ]
matrix = [
[0,1,2,0],
[3,4,5,2],
[1,3,1,5]
];
test(matrix);
console.log(matrix); // [ [ 0, 0, 0, 0 ], [ 0, 4, 5, 0 ], [ 0, 3, 1, 0 ] ]
console.log(new Date().getTime() - start.getTime()); // 8
时间复杂度: 记录有0存在行和列,时间复杂度为$O(2MN)$,清空这些行和列,时间复杂度为$O(2MN)$,所以总时间复杂度为$O(4MN)=O(MN)$
空间复杂度: 空间复杂度为$O(M+N)$
本文由 李海平 创作,采用 知识共享署名4.0
国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Aug 24,2019