zoukankan      html  css  js  c++  java
  • [LeetCode#200]Number of Islands

    Problem:

    Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

    Example 1:

    11110
    11010
    11000
    00000

    Answer: 1

    Example 2:

    11000
    11000
    00100
    00011

    Answer: 3

    Analysis:

    This problem is really really tricky, you may try to use dynamic programming to solve this problem, but it actually very hard to define. Since wheather a island is vlaid or not, it depends no only on the islands appeared before it, it also depends on the islands after it. 
    
    Wrong solution 1:
    Try to check grids around the grid to decide if a grid is a isolated is island.
    But how many isolated regions in total, how do you answer this question?
    
    Solution 1
    public int numIslands(char[][] grid) {
            if (grid == null)
                return 0;
            if (grid.length == 0 || grid[0].length == 0)
                return 0;
            int sum = (grid[0][0] == '1') ? 1 : 0;
            for (int i = 0; i < grid.length; i++) {
                for (int j = 0; j < grid[0].length; j++) {
                    if (i != 0 && j != 0) {
                        if (grid[i][j-1] == '0' && grid[i-1][j] == '0' && grid[i][j] == '1')
                            sum++;
                    } else if (i == 0 && j != 0) {
                        if (grid[i][j-1] == '0' && grid[i][j] == '1')
                            sum++;
                    } else if (i != 0 && j == 0) {
                        if (grid[i-1][j] == '0' && grid[i][j] == '1')
                            sum++;
                    } else {
                        continue;
                    }
                }
            }
            return sum;
        }
    
    
    Wrong solution 2:
    Try to use dynamic prgramming, but fail to consdier and tackle some cases.
    Invariance: If a island connected with a island in left or above direction. we don't count it as a isolated region.
    
    Error cases:
    Input:
    ["111",
    "010",
    "111"]
    Output:
    2
    Expected:
    1
    
    Fail to consdier the island appears after the current island could connect to a counted island.
        
    Solution 2:
    public int numIslands(char[][] grid) {
            if (grid == null || grid.length == 0 || grid[0].length == 0)
                return 0;
            int count = 0;
            boolean is_island[] = new boolean[grid[0].length];
            for (int i = 0; i < grid.length; i++) {
                for (int j = 0; j < grid[0].length; j++) {
                    boolean flag = false;
                    if (i != 0)
                        flag = flag || is_island[j];
                    if (j != 0)
                        flag = flag ||  is_island[j-1];
                    if (flag == false && grid[i][j] == '1') {
                        count++;
                    }
                    is_island[j] = (grid[i][j] == '1');
                }
            }
            return count;
        }
        
        
    The great solution:
    Why you spend so much efforts in thinking in tradition way.
    Since once a island connect to a island, we count them as a isolated island together. And we only care about four directions of a grid. Why do we use recursive method?
    Idea:
    Once we encounter a gird == '1', we increase count, and merge all islands in the same isolated region.
    Since the grid may directly connected with current island, we must do the merge process recursively. 
    1. count a isolated region.
            for (int i = 0; i < grid.length; i++) {
                for (int j = 0; j < grid[0].length; j++) {
                    if (grid[i][j] == '1') {
                        count++;
                        merge(grid, i, j);
                    }   
                }
            }
    
    2. merge all grids in the same isolated region.
    
    if (grid[i][j] == '1') {
        count++;
        merge(grid, i, j);
    }   
    
    private void merge(char[][] grid, int i, int j) {
            if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length)
                return;
            if (grid[i][j] == '0')  return;
            grid[i][j] = '0';
            merge(grid, i-1, j);
            merge(grid, i+1, j);
            merge(grid, i, j-1);
            merge(grid, i, j+1);
    }
    
    Skills:
    1. tackle invalid index at base case rather than at fork part. 
    if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length)
        return;
        
    2. only merge island rather than water!!! otherwise, we would merge all grids on the map. 
    if (grid[i][j] == '0')  return;

    Solution:

    public class Solution {
        public int numIslands(char[][] grid) {
            if (grid == null || grid.length == 0 || grid[0].length == 0)
                return 0;
            int count = 0;
            for (int i = 0; i < grid.length; i++) {
                for (int j = 0; j < grid[0].length; j++) {
                    if (grid[i][j] == '1') {
                        count++;
                        merge(grid, i, j);
                    }   
                }
            }
            return count;
        }
        
        private void merge(char[][] grid, int i, int j) {
            if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length)
                return;
            if (grid[i][j] == '0')  return;
            grid[i][j] = '0';
            merge(grid, i-1, j);
            merge(grid, i+1, j);
            merge(grid, i, j-1);
            merge(grid, i, j+1);
        }
    }
  • 相关阅读:
    如何经营爱情!
    document.getElementById('myframe')和window.frames[i]的区别
    [WPF] 使用 MVVM Toolkit 构建 MVVM 程序
    [WPF] 使用 Visual Studio App Center 持续监视应用使用情况和问题
    centos 7执行yum update时在clean up阶段挂住
    实现线性结构转树形结构(生成无限层级菜单)
    中文分词——HMM算法
    中文分词——最大匹配法
    爱因斯坦求和约定
    jupyter notebook美化
  • 原文地址:https://www.cnblogs.com/airwindow/p/4759378.html
Copyright © 2011-2022 走看看