Set Matrix Zeros

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?

思路

參考http://www.voidcn.com/article/p-nodlrltb-bdw.html

方案一: 用2個(gè)extra array來(lái)記錄該行該列是否需要設(shè)置為0

使用兩個(gè)數(shù)組來(lái)標(biāo)記某一行或是某一列是否存在 0。這是一種 O(m + n) 空間復(fù)雜度的實(shí)現(xiàn)方式。

共3次循環(huán)

  1. 第一次循環(huán),設(shè)置這2個(gè)數(shù)組的flag
  2. 第二次循環(huán),根據(jù)rowFlgArray設(shè)置矩陣的行為0
  3. 第三次循環(huán),根據(jù)colFlgArray設(shè)置矩陣的列為0
class Solution {
    public void setZeroes(int[][] matrix) {
        /* solution 1**********************
        //SOLUTION1. O(m + n)的方法,有2個(gè)數(shù)組,分別記錄該行和該列是否需要設(shè)置為0
        if (matrix == null || matrix[0].length == 0 || matrix.length == 0) {
            return;
        }
        
        int row = matrix.length;
        int col = matrix[0].length;
        
        int[] rowFlg = new int[col];
        int[] colFlg = new int[row];
        
        //1. 設(shè)置flg
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (matrix[i][j] == 0) {
                    colFlg[i] = 1;
                    rowFlg[j] = 1;
                }
            }
        }
        
        //3. 根據(jù)flg設(shè)置row zeros
        for (int i = 0; i < row; i++) {
            if (colFlg[i] == 1) {
                for (int j = 0; j < col; j++) {
                    matrix[i][j] = 0;
                }
            }
        }
        
        //4. 根據(jù)flg設(shè)置col zeros
        for (int i = 0; i < col; i++) {
            if (rowFlg[i] == 1)
            for (int j = 0; j < row; j++) {
                matrix[j][i] = 0;
            }
        }
}

方案二:用第一行 第一列來(lái)存 該行該列是否需要被設(shè)置為0. (不需要extra space)

一共2次遍歷矩陣,+ 2次設(shè)置第一行/第一列為0(Option)

  1. 第一次遍歷找出標(biāo)記,設(shè)置第一列和第一行。
  2. 第二次遍歷使用標(biāo)記標(biāo)注矩陣,第二遍標(biāo)記的時(shí)候不能把標(biāo)記列(行)本身也遍歷一遍,所以要排除標(biāo)記行和列,從(1,1)開(kāi)始循環(huán)起走,如果碰到第一行和第一列的標(biāo)志位為0,那么將該元素設(shè)置為0。
  3. 修正第一列和第一行的其他元素:很簡(jiǎn)單,那么設(shè)置兩個(gè)額外的bool變量告訴第一行和第一列的其他元素是否要變?yōu)?.在第一遍遍歷的時(shí)候如果Matrix[i,j]==0時(shí)i和j為0,那么對(duì)應(yīng)的標(biāo)記就要為true
    流程就是第一遍遍歷全部,找出標(biāo)記;第二遍遍歷除標(biāo)記列(行)意外的元素,將必要的元素置為0.第三次遍歷標(biāo)記列(行),根據(jù)兩個(gè)標(biāo)記考慮是否將其所有元素置為0.
 /* solution 2*********************************************************/
        //用第一行 第一列來(lái)存 該行該列是否需要被設(shè)置為0. 
        //一共兩次循環(huán),第一次循環(huán),設(shè)置第一列和第一行
        //第二次循環(huán),不要循環(huán)第一行和第一列,從(1,1)開(kāi)始循環(huán)起走,如果碰到第一行和第一列的標(biāo)志位為0,那么將該元素設(shè)置為0
        //第一列和第一行如何表示需要全部設(shè)置為0呢? 在第一次掃描時(shí),用2個(gè)boolean flag來(lái)標(biāo)識(shí)
        
        if (matrix == null || matrix[0].length == 0 || matrix.length == 0) {
            return;
        }
        
        int row = matrix.length;
        int col = matrix[0].length;
        
        boolean fstRowFlg = false;
        boolean fstColFlg = false;
        
        //1. 第一次循環(huán)
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (matrix[i][j] == 0) {
                    matrix[0][j] = 0;
                    matrix[i][0] = 0;
                    if (i == 0) fstRowFlg = true;
                    if (j == 0) fstColFlg = true;
                }
            }
        }
        
        //2. 第二次循環(huán),設(shè)置去掉第一行第一列后的數(shù)組為0
        for (int i = 1; i < row; i++) {
            for (int j = 1; j < col; j++) {
                if (matrix[i][0] == 0 || matrix[0][j] == 0) {
                    matrix[i][j] = 0;
                }
            }
        }
        
        //3. set first row into zeros
        if (fstRowFlg) {
            for (int i = 0; i < col; i++) {
                matrix[0][i] = 0;
            }
        }
        
        //4. set first col into zeros
        if (fstColFlg) {
            for (int i = 0; i < row; i++) {
                matrix[i][0] = 0;
            }
        }  
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問(wèn)題, 分享了一些自己做題目的經(jīng)驗(yàn)。 張土汪:刷leetcod...
    土汪閱讀 12,935評(píng)論 0 33
  • 解題報(bào)告: 因?yàn)椴灰胑xtra space 所以運(yùn)行時(shí)間可能有點(diǎn)高,主要是兩個(gè)方法, 一個(gè)是找出這些零的位置,之...
    yanyuchen閱讀 392評(píng)論 0 0
  • 扯閑篇 為啥寫(xiě)這個(gè)題? 因?yàn)檫@題由簡(jiǎn)單到難坑真是多。值得記錄下來(lái)好好研究研究 題目 Given amxnmatri...
    Sonass閱讀 340評(píng)論 0 0
  • 動(dòng)態(tài)規(guī)劃(Dynamic Programming) 本文包括: 動(dòng)態(tài)規(guī)劃定義 狀態(tài)轉(zhuǎn)移方程 動(dòng)態(tài)規(guī)劃算法步驟 最長(zhǎng)...
    廖少少閱讀 3,668評(píng)論 0 18
  • 讀大學(xué)真的能改變命運(yùn)嗎? 也許會(huì)有人說(shuō)“當(dāng)然能,不然我們干嘛花4年時(shí)間,花父母那么多血汗錢(qián)來(lái)讀大學(xué)呢?” 為什么要...
    斃考題閱讀 357評(píng)論 0 0

友情鏈接更多精彩內(nèi)容