当前位置 : 主页 > 大数据 > 区块链 >

#200 Number of Islands

来源:互联网 收集:自由互联 发布时间:2021-06-22
正确解法:用recursion,会让码变得简单一点。首先,在recursion function的开头来确定边界条件,如果有out of bound的情况,就马上return。再次就是,对于四个方向,都做一次dfs,并且在这里

正确解法:用recursion,会让码变得简单一点。首先,在recursion function的开头来确定边界条件,如果有out of bound的情况,就马上return。再次就是,对于四个方向,都做一次dfs,并且在这里不需要用if来check边界条件,因为当我们再次进入这个方法的时候,在方法的最开头会check,如果是边界条件,会被强行退出。这样做的话有两个好处:

  1. We don’t need to care much about the condition check for four directions. Instead of doing conditional check for four times, here we only need to do once, and we can put the different cases in one single if statement, which means less complexity.

  2. Also, in the main function, we only need to call the dfs function, and the “iterations” will just happen inside the recursion, which means less code.

Time complexity: O(MN), where M and N are the dimensions of the matrix. The complexity is only MN because we will visit every place at most twice, which means O(2MN) = O(MN).

Space complexity: O(1), since I am not using extra spaces for the array. I only created constant number of new spaces to store single variables.

One interesting thing here: recursion is actually slower than iterations. Why?

  1. Iterative loops fit typical computer systems better at the hardware level: at the machine code level, a loop is just a test and a conditional jump, whereas recursion (implemented natively) involves pushing a stack frame, jumping, returning, and popping back from the stack.

  2. Iterative loops require destructive state updates, which makes them incompatible with pure (side-effect free) language semantics. This is the reason why pure languages like haskell do not have loop constructs at all, and many other functional-programming languages either lack them completely or avoid them as much as possible.

 

我的解法:我一开始用了iterative的方法,就像我当初做101的PA一样。但是用iteration会变得复杂一点。

  1. I have to use stack for DFS, and queue for BFS.

  2. Also, I need to use the while loop, as well as the peek, pop and push to manage the orders inside the while loop.

  3. Third, I have to check the conditions for all possible conditions. These conditions include the four corners, the four boundaries, and the rest positions in the middle. Since in different cases, the child nodes we want to choose are in different directions, we need several if-else statements to check all possible conditions. It is not very easy to manage because there are too many cases. If there is an error, it will be harder to find which line of code is causing the error.

 

修正后的代码:

class Solution {

   public int numIslands(char[][] grid) {

       // check basic conditions: when grid is empty

       if(grid.length == 0){

           return 0;

       }

       

       // use result to count the number of islands

       int result = 0;

       

       // loop through all points in the grid to find the

       // possible starting points of dfs

       for(int i = 0; i < grid.length; i++){

           for(int j = 0; j < grid[0].length; j++){

               if(grid[i][j] == ‘1‘){

                   result++;

                   dfs(grid, i, j);

               }

           }

       }

       return result;

       

   }

   

   

   private void dfs(char[][] grid, int i, int j){

       // check the boundaries and make sure the current value is a land

       if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == ‘0‘){

           return;

       }

       // mark the current element as visited

       grid[i][j] = ‘0‘;

       

       // check whether there is a land around the current element

       dfs(grid, i+1, j);

       dfs(grid, i-1, j);

       dfs(grid, i, j+1);

       dfs(grid, i, j-1);

   }

}

网友评论