栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Leet专题刷题Day01-DFS岛屿问题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Leet专题刷题Day01-DFS岛屿问题

Leet专题刷题Day01-DFS岛屿问题 dfs模板
    int[][] dirs = new int[][]{{0,1}, {0,-1}, {1,0}, {-1, 0}};
    public int numIslands(char[][] grid) {

    }
    void dfs(char[][] grid, int x, int y){
        for (int[] dir : dirs){
            dfs(grid, x+dir[0], y+dir[1]);
        }

    }

首先定义dirs 搜索的方向,新建dfs方法,深度搜索每一个方向,需要之后增加推出条件。

200. 岛屿数量

思路:整个网格搜索,找到一个1 就dfs把所有的1都找出来变成0,这样就是一个岛屿。在dfs的时候,下个搜索对象只能是1不然就结束。

class Solution {
    int[][] dirs = new int[][]{{0,1}, {0,-1}, {1,0}, {-1, 0}};
    public int numIslands(char[][] grid) {
        int res = 0;
        for (int i = 0; i < grid.length; i++){
            for (int j = 0; j < grid[0].length; j++){
                if (grid[i][j] == '1'){
                    res++;
                    dfs(grid, i, j);
                }
            }
        }
        return res;
    }
    void dfs(char[][] grid, int x, int y){
        grid[x][y] = '0';
        for (int[] dir : dirs){
            int next_x = x+dir[0];
            int next_y = y+dir[1];
            if (next_x >= 0 && next_x < grid.length && next_y >= 0 && next_y < grid[0].length && grid[next_x][next_y] == '1' ){
                dfs(grid, next_x, next_y);
            }
        }
    }
}
463. 岛屿的周长

思路:题目说只有一个岛屿,所以找到一个1就可以直接dfs return就好了。dfs中搜索,如果碰到边界或者是0就周长+1,如果是0就继续搜索。

class Solution {
    int[][] dirs = new int[][]{{0,1}, {0,-1}, {1,0}, {-1,0}};
    int count = 0;
    public int islandPerimeter(int[][] grid) {
        for (int i = 0; i < grid.length; i++){
            for (int j = 0; j < grid[0].length; j++){
                if (grid[i][j] == 1){
                    dfs(grid, i, j);
                    return count;
                }
            }
        }
        return -1;
    }
    void dfs(int[][] grid, int x, int y){
        grid[x][y] = 2;
        for (int[] dir : dirs){
            int next_x = x+dir[0];
            int next_y = y+dir[1];
            if (next_x < 0 || next_x >= grid.length || next_y < 0 || next_y >= grid[0].length 
                 || grid[next_x][next_y] == 0){
                count++;
                continue;
            }
            if (grid[next_x][next_y] == 1) dfs(grid, next_x, next_y);
        }

    }
}
695. 岛屿的最大面积

思路:全局遍历grid,找到1就dfs,一次找出所有连接的土地,返回面积。

class Solution {
    int[][] dir = new int[][]{{1,0}, {-1,0}, {0,1}, {0,-1}};
    public int maxAreaOfIsland(int[][] grid) {
        int res = 0;
        for (int i = 0; i < grid.length; i++){
            for (int j = 0; j < grid[0].length; j++){
                if (grid[i][j] == 1){
                    res = Math.max(res, dfs(grid, i, j));
                }
            }
        }
        return res;

    }
    int dfs(int[][] grid, int x, int y){
        int temp = 0;
        grid[x][y] = 0;
        temp++;
        for (int[] move : dir){
            int next_x = x + move[0];
            int next_y = y + move[1];
            if (next_x >= 0 && next_x < grid.length && next_y >= 0 && next_y  
934. 最短的桥 

思路:先一遍dfs遍历其中一个岛,用queue记录下每个点的坐标,让后根据坐标一层一层向外找。

class Solution {
    int[][] dirs = new int[][]{{0,1}, {0,-1}, {1,0}, {-1, 0}};
    public int shortestBridge(int[][] grid) {
        Queue queue = new linkedList<>();
        boolean visited = false;
        for (int i = 0; i < grid.length; i++){
            for (int j = 0; j < grid[0].length; j++){
                if (grid[i][j] == 1){
                    visited = true;
                    dfs_first(grid, i, j, queue);
                    break;
                }
            }
            if (visited) break;
        }
        int count = 0;
        while (!queue.isEmpty()){
            int size = queue.size();
            for (int i = 0; i < size; i++){
                int[] candidate = queue.poll();
                for (int[] dir : dirs){
                    int next_x = candidate[0] + dir[0];
                    int next_y = candidate[1] + dir[1];
                    if (next_x >= 0 && next_x < grid.length && next_y >= 0 
                        && next_y < grid[0].length){
                            if (grid[next_x][next_y] == 1 ){
                                return count;
                            } 
                            else if (grid[next_x][next_y] == 0){
                                grid[next_x][next_y] = 2;
                                queue.offer(new int[]{next_x, next_y});
                            }
                        }
                }
            }
            count++;
        }
        return -1;

    }
    void dfs_first(int[][] grid, int x, int y, Queue queue){
        grid[x][y] = 2;
        queue.offer(new int[]{x,y});
        for (int[] dir : dirs){
            int next_x = x+dir[0];
            int next_y = y+dir[1];
            if (next_x >= 0 && next_x < grid.length && next_y >= 0 && next_y < grid[0].length 
                && grid[next_x][next_y] == 1 ){
                dfs_first(grid, next_x, next_y, queue);
            }
        }
    }
}
827. 最大人工岛

思路一:把每一个0 先当成1 在用dfs 遍历返回面积,取最大面积。(超时)

class Solution {
    int[][] dirs = new int[][]{{0,1}, {0,-1}, {1,0}, {-1, 0}};
    public int largestIsland(int[][] grid) {
        int res = 0;
        for (int i = 0; i < grid.length; i++){
            for (int j = 0; j < grid[0].length; j++){
                if (grid[i][j] == 0){
                    grid[i][j] = 1;
                    res = Math.max(res, dfs(grid, i, j, new boolean[grid.length][grid[0].length]));
                    grid[i][j] = 0;
                }
            }
        }
        return res == 0 ? grid.length*grid[0].length : res;
        
    }
    int dfs(int[][] grid, int x, int y, boolean[][] visited){
        visited[x][y] = true;
        int ans = 0;
         for (int[] dir : dirs){
            int next_x = x+dir[0];
            int next_y = y+dir[1];
            if (next_x >= 0 && next_x < grid.length && next_y >= 0 && next_y < grid[0].length 
                && grid[next_x][next_y] == 1 && ! visited[next_x][next_y]){
                ans += dfs(grid, next_x, next_y, visited);
            }
        }
        return ans+1;

    }
}

思路二 寻找出每个岛屿,并讲同一岛屿用同一个value标记,存储每个岛屿的面积。然后从0开始查找找出能连接的最大的面积。

class Solution {
    public int largestIsland(int[][] grid) {
        int value = 2; // 岛屿编号
        Map islandAreas = new HashMap<>(); // 岛屿编号 -> 岛屿面积的 map
        
        for (int r = 0; r < grid.length; r++) {
            for (int c = 0; c < grid[0].length; c++) {
                if (grid[r][c] == 1) {
                    int a = area(grid, r, c, value);
                    islandAreas.put(value, a);
                    value++;
                }
            }
        }
        
        int res = 0;
        for (int r = 0; r < grid.length; r++) {
            for (int c = 0; c < grid[0].length; c++) {
                // 依次尝试填海
                int ta = thisArea(grid, r, c, islandAreas);
                res = Math.max(res, ta);
            }
        }
        
        return res;
    }
    
    // 把 (r, c) 填海之后,最大的岛屿面积
    int thisArea(int[][] grid, int r, int c, Map islandAreas) {
        if (grid[r][c] != 0) {
            return islandAreas.get(grid[r][c]);
        }
        int res = 0;
        Set adjs = new HashSet<>();
        if (inArea(grid, r-1, c) && grid[r-1][c] > 0) {
            adjs.add(grid[r-1][c]);
        }
        if (inArea(grid, r+1, c) && grid[r+1][c] > 0) {
            adjs.add(grid[r+1][c]);
        }
        if (inArea(grid, r, c-1) && grid[r][c-1] > 0) {
            adjs.add(grid[r][c-1]);
        }
        if (inArea(grid, r, c+1) && grid[r][c+1] > 0) {
            adjs.add(grid[r][c+1]);
        }
        for (int adj : adjs) {
            System.out.println("adj = " + adj);
            res += islandAreas.get(adj);
        }
        return res + 1;
    }
    
    // value 表示当前岛屿编号
    int area(int[][] grid, int r, int c, int value) {
        if (!inArea(grid, r, c)) {
            return 0;
        }
        
        if (grid[r][c] != 1) {
            return 0;
        }
        
        grid[r][c] = value;
        
        return 1 + area(grid, r - 1, c, value)
                + area(grid, r + 1, c, value)
                + area(grid, r, c - 1, value)
                + area(grid, r, c + 1, value);
        
    }
    
    boolean inArea(int[][] grid, int r, int c) {
        return 0 <= r && r < grid.length
            && 0 <= c && c < grid[0].length;
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/294816.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号