题目:Set Matrix Zeroes

如果某一行或某一列有一个是0则该行该列全部都复位零。

思路1:

数组Amxn

创建该数组行数m和列数n的数组,用其标记行和列为零的位置,在一起复位零,这样,就不会被复位后的零所影响。

但是题目说有空间复杂度O(1)的方法。

思路2:

用已有的数组中的第一行和第一列来标记其对应的坐标的列或行是否有为零的元素;

但是这样不能标记第一行和第一列的元素是否有为零的,所以需要额外两个变量来标记第一行和第一列。

package com.example.medium;

/**
 * Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place.
 * Follow up:
 * Did you use extra space?
 * A straight forward solution using O(mn) space is probably a bad idea.
 * A simple improvement uses O(m + n) space, but still not the best solution.
 * Could you devise a constant space solution?
 * @author FuPing
 *
 */
public class SetZeroes {
    /**
     * 空间复杂度O(1)
     * @param matrix
     */
    public void setZeroes2(int[][] matrix) {
        if(matrix == null)return;
        int row = matrix.length;
        int column = matrix[0].length;
        int row0 = 1,column0 = 1;
        if(row == 1 && column == 1)return;
        for(int i = 0;i < row;i++){
            for(int j = 0;j < column;j++){
                if(matrix[i][j] == 0){
                    if(i == 0){//第一行
                        row0 = 0;
                        if(j == 0)column0 = 0;//等同于第一个元素为0
                    }else if(j == 0)column0 = 0;//第一列
                    else {//在第一行和第一列的对应位置标记
                        matrix[i][0] = 0;
                        matrix[0][j] = 0;
                    }
                }
            }
        }
        for(int i = 1;i < row;i++){//行复位零
            if(matrix[i][0] == 0){
                for(int j = 0;j < column;j++)matrix[i][j] = 0;
            }
        }
        for(int i = 1;i < column;i++){//列复位零
            if(matrix[0][i] == 0){
                for(int j = 0;j < row;j++)matrix[j][i] = 0;
            }
        }
        if(row0 == 0){//第一行复位零
            for(int j = 0;j < column;j++)matrix[0][j] = 0;
        }
        if(column0 == 0){//第一列复位零
            for(int i = 0;i < row;i++)matrix[i][0] = 0;
        }
    }
    /**
     * 空间复杂度O(m + n)
     * @param matrix
     */
    public void setZeroes(int[][] matrix) {
        if(matrix == null)return;
        int row = matrix.length;
        int column = matrix[0].length;
        if(row == 1 && column == 1)return;
        int rowsFlag[] = new int[row];//行标记数组
        int columnsFlag[] = new int[column];//列标记数组
        for(int i = 0;i < row;i++){
            for(int j = 0;j < column;j++){
                if(matrix[i][j] == 0){//标记对应的行和列
                    rowsFlag[i] = 1;
                    columnsFlag[j] = 1;
                }
            }
        }
        for(int i = 0;i < row;i++){//行复位零
            if(rowsFlag[i] == 1){
                for(int j = 0;j < column;j++)matrix[i][j] = 0;
            }
        }
        for(int i = 0;i < column;i++){//列复位零
            if(columnsFlag[i] == 1){
                for(int j = 0;j < row;j++)matrix[j][i] = 0;
            }
        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        long startTime = System.currentTimeMillis();
        int matrix[][] = {{1,1,0,1,1,1,1},{1,1,1,1,1,1,1},{1,0,1,1,1,1,1},{1,1,1,1,1,1,1}};
        new SetZeroes().setZeroes2(matrix);
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                System.out.print(matrix[i][j] + " ");
            }
            System.out.println();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("程序运行时间:"+(endTime-startTime) + "ms");

    }

}