当前位置: 首页 > article >正文

32.递归、搜索、回溯之floodfill算法

0.简介

1.图像渲染

. - 力扣(LeetCode)

题目解析

算法原理

代码

class Solution {
    int[] dx = { 0, 0, 1, -1 };
    int[] dy = { 1, -1, 0, 0 };
    int m, n;
    int prev;

    public int[][] floodFill(int[][] image, int sr, int sc, int color) {
        if (image[sr][sc] == color)
            return image;
        m = image.length;
        n = image[0].length;
        prev = image[sr][sc];
        dfs(image, sr, sc, color);
        return image;
    }

    public void dfs(int[][] image, int i, int j, int color) {
        image[i][j] = color;
        for (int k = 0; k < 4; k++) {
            int x = i + dx[k], y = j + dy[k];
            if (x >= 0 && x < m && y >= 0 && y < n && image[x][y] == prev) {
                dfs(image, x, y, color);
            }
        }
    }
}

2.岛屿数量

. - 力扣(LeetCode)

题目解析

算法原理

代码

class Solution {
    boolean[][] vis;
    int m, n;
    int[] dx = { 0, 0, -1, 1 };
    int[] dy = { 1, -1, 0, 0 };

    public int numIslands(char[][] grid) {
        m = grid.length;
        n = grid[0].length;
        vis = new boolean[m][n];
        int ret = 0;
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++) {
                if (!vis[i][j] && grid[i][j] == '1') {
                    ret++;
                    dfs(grid, i, j);
                }
            }
        return ret;
    }

    public void dfs(char[][] grid, int i, int j) {
        vis[i][j] = true;
        for (int k = 0; k < 4; k++) {
            int x = i + dx[k], y = j + dy[k];
            if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && grid[x][y] == '1') {
                dfs(grid, x, y);
            }
        }
    }
}

3.岛屿的最大面积

. - 力扣(LeetCode)

题目解析

算法原理

代码

class Solution {
    boolean[][] vis;
    int m, n;
    int[] dx = { 0, 0, -1, 1 };
    int[] dy = { 1, -1, 0, 0 };
    int count;

    public int maxAreaOfIsland(int[][] grid) {
        m = grid.length;
        n = grid[0].length;
        vis = new boolean[m][n];
        int ret = 0;
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++) {
                if (!vis[i][j] && grid[i][j] == 1) {
                    count = 0;
                    dfs(grid, i, j);
                    ret = Math.max(ret, count);
                }
            }
        return ret;
    }

    public void dfs(int[][] grid, int i, int j) {
        count++;
        vis[i][j] = true;
        for (int k = 0; k < 4; k++) {
            int x = i + dx[k], y = j + dy[k];
            if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && grid[x][y] == 1)
                dfs(grid, x, y);
        }
    }
}

4.被围绕的区域

130. 被围绕的区域 - 力扣(LeetCode)

题目解析

算法原理

代码

class Solution {
    int m, n;
    int[] dx = { 1, -1, 0, 0 };
    int[] dy = { 0, 0, 1, -1 };

    public void solve(char[][] board) {
        m = board.length;
        n = board[0].length;
        // 1. 先把边界的 O 相连的联通块,全部修改成 '.'
        for (int j = 0; j < n; j++) {
            if (board[0][j] == 'O')
                dfs(board, 0, j);
            if (board[m - 1][j] == 'O')
                dfs(board, m - 1, j);
        }
        for (int i = 0; i < m; i++) {
            if (board[i][0] == 'O')
                dfs(board, i, 0);
            if (board[i][n - 1] == 'O')
                dfs(board, i, n - 1);
        }
        // 2. 还原
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++) {
                if (board[i][j] == '.')
                    board[i][j] = 'O';
                else if (board[i][j] == 'O')
                    board[i][j] = 'X';
            }
    }

    public void dfs(char[][] board, int i, int j) {
        board[i][j] = '.';
        for (int k = 0; k < 4; k++) {
            int x = i + dx[k], y = j + dy[k];
            if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O') {
                dfs(board, x, y);
            }
        }
    }
}

5.太平洋大西洋水流问题

. - 力扣(LeetCode)

题目解析

算法原理

代码

class Solution {
    int m, n;
    int[] dx = { 0, 0, 1, -1 };
    int[] dy = { 1, -1, 0, 0 };

    public List<List<Integer>> pacificAtlantic(int[][] h) {
        m = h.length;
        n = h[0].length;
        boolean[][] pac = new boolean[m][n];
        boolean[][] atl = new boolean[m][n];
        // 1. 先处理 pac 洋
        for (int j = 0; j < n; j++)
            dfs(h, 0, j, pac);
        for (int i = 0; i < m; i++)
            dfs(h, i, 0, pac);
        // 2. 再处理 atl 洋
        for (int i = 0; i < m; i++)
            dfs(h, i, n - 1, atl);
        for (int j = 0; j < n; j++)
            dfs(h, m - 1, j, atl);
        // 3. 提取结果
        List<List<Integer>> ret = new ArrayList<>();
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
                if (pac[i][j] && atl[i][j]) {
                    List<Integer> tmp = new ArrayList<>();
                    tmp.add(i);
                    tmp.add(j);
                    ret.add(tmp);
                }

        return ret;
    }

    public void dfs(int[][] h, int i, int j, boolean[][] vis) {
        vis[i][j] = true;
        for (int k = 0; k < 4; k++) {
            int x = i + dx[k], y = j + dy[k];
            if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && h[x][y] >= h[i][j]) {
                dfs(h, x, y, vis);
            }
        }
    }
}

6.扫雷问题

. - 力扣(LeetCode)

题目解析

算法原理

代码

class Solution {
    int[] dx = { 0, 0, 1, -1, 1, 1, -1, -1 };
    int[] dy = { 1, -1, 0, 0, 1, -1, 1, -1 };
    int m, n;

    public char[][] updateBoard(char[][] board, int[] click) {
        m = board.length;
        n = board[0].length;
        int x = click[0], y = click[1];
        if (board[x][y] == 'M') // 如果直接点到地雷,游戏结束
        {
            board[x][y] = 'X';
            return board;
        }
        dfs(board, x, y);
        return board;
    }

    public void dfs(char[][] board, int i, int j) {
        // 统计⼀下周围地雷的个数
        int count = 0;
        for (int k = 0; k < 8; k++) {
            int x = i + dx[k], y = j + dy[k];
            if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'M') {
                count++;
            }
        }
        if (count == 0) // 周围没有地雷
        {
            board[i][j] = 'B';
            for (int k = 0; k < 8; k++) {
                int x = i + dx[k], y = j + dy[k];
                if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'E') {
                    dfs(board, x, y);
                }
            }
        } else {
            board[i][j] = (char) ('0' + count);
            return;
        }
    }
}

7.机器人的运动范围

. - 力扣(LeetCode)

题目解析

算法原理

代码

class Solution {
    int m, n, k;
    boolean[][] vis;
    int[] dx = { 1, -1, 0, 0 };
    int[] dy = { 0, 0, 1, -1 };
    int ret;

    public int movingCount(int _m, int _n, int _k) {
        m = _m;
        n = _n;
        k = _k;
        vis = new boolean[m][n];
        dfs(0, 0);
        return ret;
    }

    public void dfs(int i, int j) {
        ret++;
        vis[i][j] = true;
        for (int k = 0; k < 4; k++) {
            int x = i + dx[k], y = j + dy[k];
            if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && check(x, y)) {
                dfs(x, y);
            }
        }
    }

    public boolean check(int i, int j) {
        int tmp = 0;
        while (i != 0) {
            tmp += i % 10;
            i /= 10;
        }
        while (j != 0) {
            tmp += j % 10;
            j /= 10;
        }
        return tmp <= k;
    }
}


http://www.kler.cn/a/308161.html

相关文章:

  • Spring高手之路26——全方位掌握事务监听器
  • 虚幻引擎 CEO 谈元宇宙:发展、策略与布局
  • Spring MVC 与 JSP 数据传输
  • 前端--> nginx-->gateway产生的跨域问题分析
  • 每日一练:二分查找-搜索插入位置
  • [代码随想录Day10打卡] 理论基础 232.用栈实现队列 225. 用队列实现栈 20. 有效的括号 1047. 删除字符串中的所有相邻重复项
  • 【D3.js in Action 3 精译_023】3.3 使用 D3 将数据绑定到 DOM 元素
  • 掌握这几个酱酒特点术语,聊天更显内行
  • 17、电科院FTU检测标准学习笔记-录波性能
  • GeoPandas在地理空间数据分析中的应用
  • ElasticSearch-2-核心语法集群高可用实战-Week2
  • 二叉树总结篇(2)
  • Imagen:重塑图像生成领域的革命性突破
  • websocket 和sip 在协议层面有哪些区别,为什么要各自这样设置协议
  • 鸿蒙开发笔记_电商严选02_登录页面跳转到我的页面、并传值
  • Google 工程师开始用Rust 语言开发 Android 固件
  • 简单了解Maven与安装
  • 数组与贪心算法——649、678、420 数字与贪心 343(3中1难)
  • 【算法】差分思想:强大的算法技巧
  • Sybase「退役」在即,某公共卫生机构如何实现 SAP Sybase 到 PostgreSQL 的持续、无缝数据迁移?
  • MySQL日志binlog和redo log区别
  • 算法面经手撕系列(3)--手撕LayerNormlization
  • 【算法】滑动窗口—最小覆盖子串
  • MyBatis的配置文件详解
  • druid jdbc 执行 sql 输出 开销耗时
  • Linux下抓包分析Java应用程序HTTP接口调用:基于tcpdump与Wireshark的综合示例