Leetcode 463. Island Perimeter 解題

好久沒有刷題,甚是懷念這種刷題的感覺
最近有刷杭電oJ POJ也試着刷了一下,還有個國外的平臺我忘了叫啥了
感覺LeetCode的平臺很人性化,能夠在提交之前自己嘗試運行,並且能夠告訴你WA之前最後一次測試數據是什麼,方便尋找錯誤原因,並且AC之後還能看到別人的AC代碼(這是我最欣賞的一點!)這樣就能學習到更好的算法,不過它的playground我還不是很會用,調試還得在本地進行。但是測試用例有點少,題目偏簡單,相比之下杭電OJ和POJ的測試條件就有點苛刻了

看下題目

You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells). The island doesn’t have “lakes” (water inside that isn’t connected to the water around the island). One cell is a square with side length 1. The grid is rectangular, width and height don’t exceed 100. Determine the perimeter of the island.

題目大意是:給定一個圖,以0和1表示,1表示陸地,0表示海洋,整個數組都是被海洋包圍,意味着邊界之外就是海洋,這個陸地是沒有湖的(也就是陸地中間一圈是水)你要找到這個陸地的邊界周長

Example:

[[0,1,0,0],
[1,1,1,0],
[0,1,0,0],
[1,1,0,0]]

Answer: 16
Explanation: The perimeter is the 16 yellow stripes in the image below:
這裏寫圖片描述

解題思路

遍歷整個數組,對每一個是陸地的格子,判斷它的四周是否是陸地邊緣
陸地邊緣的判定標準是:1)是海洋和陸地的分界線 2)是整個數組的邊緣
滿足這兩個條件之一的就是一條邊界,一個格子最多有4條邊界,把邊界累加就可以了。
下面是代碼:

class Solution {
public:
    int islandPerimeter(vector<vector<int>>& grid) {
        int edgs=0;
        int height=grid.size();
        int width=grid[0].size();

        //traverse each cell of the array,check its neighbor
        for(int i =0;i<height;i++){
            for(int j=0;j<width;j++){
                //if there is a island
                if(grid[i][j]==1){
                    //up 
                    if((i-1)<0||grid[i-1][j]==0){
                        edgs++;
                    }
                    //down
                    if((i+1)>=height||grid[i+1][j]==0){
                        edgs++;
                    }
                    //left
                    if((j-1)<0||grid[i][j-1]==0){
                        edgs++;
                    }
                    //right
                    if((j+1)>=width||grid[i][j+1]==0){
                        edgs++;
                    }
                }
            }
        }
        return edgs;
    }
};

更好的算法

我在瀏覽其他AC代碼的時候看到一個,這個思路很有趣
同樣是遍歷整個數組,然後每遇到一個陸地,就累計陸地的數目,並且判斷陸地內的區域的右邊和下面是否同樣是陸地,如果是就表明這個不是邊界,將這樣的數量累加,最後用陸地數量*4-非邊界數量即可
只判斷右邊和下面的目的是爲了避免重複計算
下面是代碼:

class Solution {
public:
    int islandPerimeter(vector<vector<int>>& grid) {
        if (grid.empty()) return 0;
        int m = grid.size();
        int n = grid[0].size();
        int islands = 0, neighbours = 0;
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
                if (grid[i][j] == 1) {
                    islands++;
                    if (i < m - 1 && grid[i + 1][j] == 1) neighbours++;
                    if (j < n - 1 && grid[i][j + 1] == 1) neighbours++;
                }
        return islands * 4 - neighbours * 2;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章