本文正在参加「Java主题月 - Java 刷题打卡」,详情查看 活动链接
题目描述
零矩阵
编写一种算法,若M × N矩阵中某个元素为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]
]
思路分析
首先来个最简单的解法,就是暴力破解,用一个该List<int[]> list
将对于矩阵位置的为 0 的下标都记录下来,然后再遍历矩阵中的值,对行和列分别进行置 0,该解法的时间复杂度是,空间复杂度也是或。
还有一种解法是,整个矩阵总归是行和列是否有 0 ,我们可以统一移植到首行和首列。我们先判断首行和首列是否有 0,利用两个变量进行记录,该解法的时间复杂度是,空间复杂度也是。
代码展示
解法一:暴力破解,先将矩阵中为 0 的坐标都记录下来,最后再遍历,将对应的位置置为 0。时间复杂度是,空间复杂度是或。
public void setZeroes(int[][] matrix) {
List<int[]> list = new ArrayList<>();
for (int i = 0; i < matrix.length; i++) { //matrix.length = 4
for (int j = 0;j < matrix[0].length;j++){
if (matrix[i][j] == 0){
list.add(new int[]{i,j});
}
}
}
for (int i = 0;i < list.size();i++){
int[] temp = list.get(i);
int a1 = temp[0];
for (int j = 0;j < matrix[0].length;j++){
matrix[a1][j] = 0;
}
int a2 = temp[1];
for (int k = 0;k < matrix.length;k++){
matrix[k][a2] = 0;
}
}
解法二:上面解法的时间复杂度是,空间复杂度是或,时间复杂度肯定是不能简化,因为需要都遍历下来,但是空间复杂度是可以优化的,因为我们都可以移植到第一行第一列,但是首先要先记住第一行/列是否有 0,然后再进行处理。
public void setZeroes(int[][] matrix) {
int m = matrix.length;
int n = matrix[0].length;
boolean firstCol = false; //列
boolean firstRow = false; //行
for (int i = 0; i < m; i++) {
if (matrix[i][0] == 0) {
firstCol = true; //第一列有0
break;
}
}
for (int j = 0; j < n; j++) {
if (matrix[0][j] == 0) {
firstRow = true; //第一行有0
break;
}
}
for (int i = 1; i < m; i++) { //给第一行或这一列赋值为0
for (int j = 1; j < n; j++) {
if (matrix[i][j] == 0) {
matrix[i][0] = matrix[0][j] = 0;
}
}
}
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;
}
}
}
if (firstRow){
for (int i = 0;i < n;i++){
matrix[0][i] = 0;
}
}
if (firstCol){
for (int j = 0;j < m;j++){
matrix[j][0] = 0;
}
}
}
总结
在解答该类题目时,首先可以尝试暴力破解,然后在结合矩阵和题目的特点,对空间复杂度进行优化。