542. 01 Matrix

Description

Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell.

The distance between two adjacent cells is 1.

Example 1:
Input:

0 0 0
0 1 0
0 0 0

Output:

0 0 0
0 1 0
0 0 0

Example 2:
Input:

0 0 0
0 1 0
1 1 1

Output:

0 0 0
0 1 0
1 2 1

Note:

  1. The number of elements of the given matrix will not exceed 10,000.
  2. There are at least one 0 in the given matrix.
  3. The cells are adjacent in only four directions: up, down, left and right.

Solution

BFS, time O(m * n), space O(m * n)

跟"286. Walls and Gates"完全相同的解法拟淮。
注意,這道題用的是BFS level traversal甜刻,而非Dijikstra纵朋,所以需要在進隊列的時候更新dis艺蝴,而非出隊列的時候!

class Solution {
    public static final int[][] DIRECTIONS = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    
    public int[][] updateMatrix(int[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return matrix;
        }
        
        int m = matrix.length;
        int n = matrix[0].length;
        int[][] dis = new int[m][n];
        for (int[] row : dis) {
            Arrays.fill(row, Integer.MAX_VALUE);
        }
        
        Queue<int[]> queue = new LinkedList<>();
        
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (matrix[i][j] == 0) {
                    queue.offer(new int[]{i, j});
                    dis[i][j] = 0;
                }
            }
        }
        
        while (!queue.isEmpty()) {
            int[] pos = queue.poll();
            int neighborDis = dis[pos[0]][pos[1]] + 1;
            
            for (int[] direction : DIRECTIONS) {
                int x = pos[0] + direction[0];
                int y = pos[1] + direction[1];
                // check isValid here! otherwise dis[x][y] might be broken
                if (x < 0 || x >= m || y < 0 || y >= n || dis[x][y] < Integer.MAX_VALUE) {
                    continue;
                }

                dis[x][y] = neighborDis;
                queue.offer(new int[] {x, y});
            }
        }
        
        return dis;
    }
}

DFS: TLE

DP, time O(mn), space O(mn)

也可以用DP來解,因為每個位置(i, j)的結(jié)果只依賴與它上下左右鄰居到0的距離乡小。

用兩遍遍歷即可解決啦。有一個坑是饵史,由于后面會對鄰居的dis加一進行比較满钟,所以不能將dis[][]初始化成Integer.MAX_VALUE,會overflow的胳喷!

class Solution {
    public int[][] updateMatrix(int[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return matrix;
        }
        
        int m = matrix.length;
        int n = matrix[0].length;
        int[][] dis = new int[m][n];
        for (int[] row : dis) {
            Arrays.fill(row, 10001);    // shouldn't use Integer.MAX_VALUE! Add cause overflow
        }
        
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (matrix[i][j] == 0) {
                    dis[i][j] = 0;
                    continue;
                }
                
                if (i > 0) {
                    dis[i][j] = Math.min(1 + dis[i - 1][j], dis[i][j]);
                }
                
                if (j > 0) {
                    dis[i][j] = Math.min(1 + dis[i][j - 1], dis[i][j]);
                }
            }
        }
        
        for (int i = m - 1; i >= 0; --i) {
            for (int j = n - 1; j >= 0; --j) {
                if (i < m - 1) {
                    dis[i][j] = Math.min(1 + dis[i + 1][j], dis[i][j]);
                }
                if (j < n - 1) {
                    dis[i][j] = Math.min(1 + dis[i][j + 1], dis[i][j]);
                }
            }
        }
        
        return dis;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末湃番,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子吭露,更是在濱河造成了極大的恐慌吠撮,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件讲竿,死亡現(xiàn)場離奇詭異泥兰,居然都是意外死亡择浊,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門逾条,熙熙樓的掌柜王于貴愁眉苦臉地迎上來琢岩,“玉大人,你說我怎么就攤上這事师脂〉?祝” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵吃警,是天一觀的道長糕篇。 經(jīng)常有香客問我,道長酌心,這世上最難降的妖魔是什么拌消? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮安券,結(jié)果婚禮上墩崩,老公的妹妹穿的比我還像新娘。我一直安慰自己侯勉,他們只是感情好鹦筹,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著址貌,像睡著了一般铐拐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上练对,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天遍蟋,我揣著相機與錄音,去河邊找鬼螟凭。 笑死虚青,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的赂摆。 我是一名探鬼主播挟憔,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼烟号!你這毒婦竟也來了绊谭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤汪拥,失蹤者是張志新(化名)和其女友劉穎达传,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡宪赶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年宗弯,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片搂妻。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蒙保,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出欲主,到底是詐尸還是另有隱情邓厕,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布扁瓢,位于F島的核電站详恼,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏引几。R本人自食惡果不足惜昧互,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望伟桅。 院中可真熱鬧敞掘,春花似錦、人聲如沸贿讹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽民褂。三九已至,卻和暖如春疯潭,著一層夾襖步出監(jiān)牢的瞬間赊堪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工竖哩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留哭廉,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓相叁,卻偏偏與公主長得像遵绰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子增淹,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容