leetcode小岛问题2道 (DFS的递归法和迭代法应用)

695 Max Area of Island

Recursive递归

时间复杂度O(R*C):所有坐标遍历一遍
空间复杂度O(R*C):seen[][]
所有坐标遍历一遍,对每个坐标计算其所在的的island的大小,并与历史最大值比较,取max。计算island的大小时,在1.此坐标不出界2.此坐标不为0 3.此坐标没被计算过(每个坐标只能归入一个island)的情况下,递归计算其与上下左右的面积之和
class Solution {
    int[][] grid;
    boolean[][] seen;

    public int area(int r, int c) {
        if (r < 0 || r >= grid.length || c < 0 || c >= grid[0].length ||
                seen[r][c] || grid[r][c] == 0)
            return 0;
        seen[r][c] = true;
        return (1 + area(r+1, c) + area(r-1, c)
                  + area(r, c-1) + area(r, c+1));
    }

    public int maxAreaOfIsland(int[][] grid) {
        this.grid = grid;
        seen = new boolean[grid.length][grid[0].length];
        int ans = 0;
        for (int r = 0; r < grid.length; r++) {
            for (int c = 0; c < grid[0].length; c++) {
                ans = Math.max(ans, area(r, c));
            }
        }
        return ans;
    }
}

Iterative迭代

时间复杂度O(R*C):所有坐标遍历一遍
空间复杂度O(R*C):seen[][]
初始化ans=0。所有坐标开始遍历,遇到首个不为0的坐标(可以确定其seen[][]==false),初始化这附近一片1的面积shape=0,构造stack, 压栈,改变seen[][]状态为true,即完成循环前的工作。while栈不为空的情况下,出栈一个,计数+1,检查此坐标上下左右的坐标是否满足上述3个条件,满足则也入栈,反复进行,得出遍历到此点所在的island的面积,同样max(历史值ans, 单次面积)。
class Solution {
    public int maxAreaOfIsland(int[][] grid) {
        boolean[][] seen = new boolean[grid.length][grid[0].length];
        int[] dr = new int[]{1, -1, 0, 0};
        int[] dc = new int[]{0, 0, 1, -1};

        int ans = 0;
        for (int r0 = 0; r0 < grid.length; r0++) {
            for (int c0 = 0; c0 < grid[0].length; c0++) {
                if (grid[r0][c0] == 1 && !seen[r0][c0]) {
                    int shape = 0;
                    Stack<int[]> stack = new Stack();
                    stack.push(new int[]{r0, c0});
                    seen[r0][c0] = true;
                    while (!stack.empty()) {
                        int[] node = stack.pop();
                        int r = node[0], c = node[1];
                        shape++;
                        for (int k = 0; k < 4; k++) {
                            int nr = r + dr[k];
                            int nc = c + dc[k];
                            if (0 <= nr && nr < grid.length &&
                                    0 <= nc && nc < grid[0].length &&
                                    grid[nr][nc] == 1 && !seen[nr][nc]) {
                                stack.push(new int[]{nr, nc});
                                seen[nr][nc] = true;
                            }
                        }
                    }
                    ans = Math.max(ans, shape);
                }
            }
        }
        return ans;
    }
}

200. Number of Islands

Example 1:1是小岛0是水,周围都是水,求岛的个数。遇到1就把与其连接的陆地用深度优先遍历都变为0,下次遇到就不会重复计算个数了。

11110
11010
11000
00000
Answer: 1

class Solution {
    public void turnzero(char[][] g, int x, int y)
    {
        if(x>=0 && x<g.length && y>=0 && y<g[0].length && g[x][y] == '1')
        {
            g[x][y] = '0';
            turnzero(g,x+1,y);
            turnzero(g,x-1,y);
            turnzero(g,x,y+1);
            turnzero(g,x,y-1);
        }
    }
    public int numIslands(char[][] grid) {
        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++;
                    turnzero(grid,i,j);
                }
            }
        }
        return count;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值