【递归回溯之floodfill算法专题练习】

news2024/12/26 5:39:08

1. 图像渲染

class Solution {
    int dx[4] = {0, 0, -1, 1};
    int dy[4] = {1, -1, 0, 0};
    int m, n;
    int oldcolor; 
public:
    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {
        oldcolor = image[sr][sc]; // 保存原始像素值
        m = image.size();
        n = image[0].size();
        if(image[sr][sc] == color)
            return image;
        // 先将起点位置修改为color
        image[sr][sc] = color;
        dfs(image, sr, sc, color);
        return image;
    }

    void dfs(vector<vector<int>>& image, int sr, int sc, int color)
    {
        for(int k = 0; k < 4; k++)
        {
            int x = dx[k] + sr;
            int y = dy[k] + sc;
            if(x >= 0 && x < m && y >= 0 && y < n && image[x][y] == oldcolor)
            {
                image[x][y] = color;
                dfs(image, x ,y , color);
            }
        }
    }
};

 2. 岛屿数量

class Solution {
    int dx[4] = {0, 0, -1, 1};
    int dy[4] = {1, -1, 0, 0};
    bool vis[301][301] = { false };
    int m, n;
public:
    int numIslands(vector<vector<char>>& grid) {
        int ret = 0;
        m = grid.size();
        n = grid[0].size();
        for(int i = 0; i < m; i++)
            for(int j = 0; j < n; j++)
                // 如果陆地没有标记并且为1,统计结果
                if(!vis[i][j] && grid[i][j] == '1') 
                {
                    ret++;
                    vis[i][j] = true;
                    dfs(grid, i, j);  // 把这块岛屿相连的陆地全都标记  
                }
        return ret;         
    }

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

3. 岛屿的最大面积

class Solution {
    int dx[4] = {0, 0, -1, 1};
    int dy[4] = {1, -1, 0, 0};
    bool vis[51][51] = { false };
    int m, n;
    int count = 0, ret = 0;
public:
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        m = grid.size();
        n = grid[0].size();
        
        for(int i = 0; i < m; i++)
            for(int j = 0; j < n; j++)
                // 如果陆地没有标记并且为1,此时开始深搜
                if(!vis[i][j] && grid[i][j] == 1) 
                {
                    count = 0;
                    dfs(grid, i, j);  // 把这块岛屿相连的陆地全都标记并统计面积 
                    ret = max(ret, count);
                }
        return ret;
    }

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

4. 被围绕的区域

 

正难则反,我们可以四周开始向里面遍历,但凡能深搜到的,都是不能修改的,此时我们将遍历到的标记一下,其余的全部修改成x即可。

class Solution {
    int dx[4] = {0, 0, -1, 1};
    int dy[4] = {1, -1, 0, 0};
    int m, n;
public:
    void solve(vector<vector<char>>& board) {
        m = board.size();
        n = board[0].size();
        
        // 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';
            }           
    }

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

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

class Solution {
    int dx[4] = {0, 0, -1, 1};
    int dy[4] = {1, -1, 0, 0};
    int m, n;
public:
    vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) {
        m = heights.size();
        n = heights[0].size();

        vector<vector<bool>> pac(m, vector<bool>(n));
        vector<vector<bool>> atl(m, vector<bool>(n));
        
        // 先处理第一行和第一列 - 太平洋
        for(int j = 0; j < n; j++) dfs(heights, 0, j, pac);
        for(int i = 0; i < m; i++) dfs(heights, i, 0, pac);

        // 再处理最后一行和最后一列 - 大西洋
        for(int j = 0; j < n; j++) dfs(heights, m - 1, j, atl);
        for(int i = 0; i < m; i++) dfs(heights, i, n - 1, atl);

        vector<vector<int>> ret;
        for(int i = 0; i < m; i++)
            for(int j = 0; j < n; j++)
                if(atl[i][j] && pac[i][j])
                    ret.push_back({i, j});
        return ret;
    }

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

6. 扫雷游戏

class Solution {
    int dx[8] = {0, 0, 1, -1, 1, 1, -1, -1};
    int dy[8] = {1, -1, 0, 0, 1, -1 ,1, -1};
    int m, n;
public:
    vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click) {
        m = board.size();
        n = board[0].size();
        // 如果运气背,起始位置就是地雷,直接返回
        int x = click[0];
        int y = click[1];
        if(board[x][y] == 'M')
        {
            board[x][y] = 'X';
            return board;
        }
        dfs(board, x, y);
        return board;
    }

    void dfs(vector<vector<char>>& board, int i, int j)
    {
        // 先统计一下周围地雷的个数
        int count = 0;
        for(int k = 0; k < 8; k++)
        {
            int x = dx[k] + i;
            int y = dy[k] + j;
            // M 表示地雷
            if(x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'M')
            {
                count++;
            }
        }
        // 该位置处存在地雷
        if(count)
        {
            // 存在地雷就不需要展开
            board[i][j] = count + '0';
            return;
        }
        else
        {   // 周围八个位置都要展开
            // 先把自己标记成空方块
            board[i][j] = 'B';
            for(int k = 0; k < 8; k++)
            {
                int x = dx[k] + i;
                int y = dy[k] + j;
                // E 表示没有点击的位置
                if(x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'E')
                {
                    dfs(board, x, y);
                }
            }
        }
    }
};

7. 机器人的运动范围

class Solution {
    int dx[4] = {0, 0, -1, 1};
    int dy[4] = {-1, 1, 0, 0};
    int ret;
    bool vis[101][101] = { false };
public:
    int wardrobeFinishing(int m, int n, int cnt) {
        dfs(0, 0, m, n, cnt);
        return ret;
    }

    bool check(int i, int j, int cnt)
    {
        // 求数位之和
        int tmp = 0;
        while(i)
        {
            tmp += i % 10;
            i /= 10;
        }
        while(j)
        {
            tmp += j % 10;
            j /= 10;
        }
        return tmp <= cnt;
    }

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

                dfs(x, y, m, n, cnt);
            }
        }
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2083340.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java常用API(BigDecimal)

用于小数的精确计算 用来表示很大的小数 构造方法获取BigDecimal对象 public BigDecimal(double val) public BigDecimal(string val) 静态方法获取BigDecimal对象 public static BigDecimal value0f(double val) 1.通过传递double类型的小数来创建对象 这种方式有可能…

Linux|软件开发的基础概念|软件的源码本地编译和交叉编译概念

前言&#xff1a; 本文主要讲述软件的源码本地编译和交叉编译的基本概念&#xff0c;首先&#xff0c;是介绍什么是本地编译&#xff0c;什么是交叉编译&#xff0c;其次&#xff0c;本地编译和交叉编译到底是有什么用处&#xff0c;最后是交叉编译和本地编译的具体应用场景 …

边听边打?不再是难题,4款音频转文字神器推荐

无论是会议记录、课堂笔记还是采访录音&#xff0c;能快速准确地转录成文本&#xff0c;那可是大大提高了工作效率。市面上有几款工具在这方面做得不错&#xff0c;比如365在线转文字、布谷鸟配音、腾讯云语音识别和Speechnotes。今天就来个大比拼&#xff0c;看看它们各自的表…

人机交互的频率、时长、周期

人机交互的频率是指用户与系统互动的频繁程度&#xff1b;时长是每次互动的持续时间&#xff1b;周期是指在特定时间段内进行互动的规律或间隔。人机交互的频率、时长和周期通常与以下因素有关&#xff1a; &#xff08;1&#xff09;任务复杂性&#xff1a;复杂任务需要更多的…

docker部署clickhouse

1. 创建相关配置目录 mkdir -P /data/clickhouse/data mkdir -P /data/clickhouse/conf mkdir -P /data/clickhouse/log 2. 拉取镜像 # 下载最新版本clickhouse docker pull clickhouse/clickhouse-server # 下载指定版本clickhouse docker pull clickhouse/clickhouse…

电商数据分析:如何抓住关键指标提高销售额

在电商运营中&#xff0c;数据分析是不可或缺的一环。通过精准的数据分析&#xff0c;商家可以更好地了解市场动态、优化运营策略&#xff0c;从而提升销售业绩。然而&#xff0c;很多运营者在面对海量数据时常常无从下手。那么&#xff0c;电商运营到底该如何进行数据分析&…

Chapter 05 计算属性

欢迎大家订阅【Vue2Vue3】入门到实践 专栏&#xff0c;开启你的 Vue 学习之旅&#xff01; 文章目录 前言一、基础语法二、计算属性vs方法三、完整写法 前言 Vue.js 提供了丰富的功能&#xff0c;帮助开发者高效地构建用户界面。本篇文章详细讲解了其计算属性的基本语法、应用…

笔记整理—uboot启动过程(7)malloc初始化与内存环境变量

上一章说到了env环境变量并对前两章有关init_sequence部分做了总结&#xff0c;这一章将要对uboot部分的malloc初始化以及内存环境变量进行相关的说明。 mem_malloc_init是用于初始化uboot堆管理器的。自己维护了一段内存&#xff0c;就可用进行malloc和free的操作了。那么这个…

Mac/Linux系统matplotlib中文支持问题

背景 matplotlib是python中最常用的数据可视化分析工具&#xff0c;Mac和Linux系统无中文字体&#xff0c;不支持中文显示&#xff08;希望后续可以改进&#xff09;&#xff0c;需要进行字体的下载和设置才能解决。笔者经过实践&#xff0c;发现Mac系统和Linux系统解决方案略…

数据结构算法基础-单链表的新建(头插法、尾插法)

1.头插法 2.尾插法 3.代码及运行结果 设输入的值为&#xff1a;3 4 5 6 7&#xff08;到9999终止读值&#xff09; #include <stdio.h> #include <stdlib.h> typedef int ElemType;typedef struct LNode{ElemType data;struct LNode *next; }LNode,*LinkList;LinkL…

02 vue3之ref全局桶

ref 接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象仅有一个 .value property&#xff0c;指向该内部值。 <template><div class"">Ref:{{ name.a }}</div><button click"change()">change</button> </te…

如何用Java构建学生档案管理系统:实现学生信息的高效管理

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

Mybatis缓存、java反射(精简秒懂版)

目录 一、缓存 1.mybatis一级缓存 2.mybatis二级缓存 开启二级缓存 二、Java反射机制概念 1.Java反射概念 2.Java反射相关api 三、Java反射相关类 1.Class类&#xff08;反射基础&#xff09; &#xff08;1&#xff09;Object类中的getClass方法&#xff1a;适用于通过对…

sdk监控平台

监控平台实现方案 监测网页加载时长是关注的是以下5个过程&#xff1a; 1.重定向时间&#xff1a;获取此网页前重定向所花费的时间 2.DNS域名查找时间&#xff1a;查找此网页的DNS所花费的时间 3.TCP服务器连接时间&#xff1a;用户连接到您的服务器所需的时间 4.服务器响应…

基于文心智能体平台打造的德语学习助手

德语学习助手&#xff1a;您的智能德语语言学专家 在学习德语的道路上&#xff0c;是否曾遇到过这样的困扰&#xff1a;不知道自己的德语水平如何&#xff1f;学习过程中缺乏系统的计划&#xff1f;在日常交流中总是担心表达不准确&#xff1f;或者在面对德语文本时&#xff0c…

[深度学习] 时间序列分析工具TSLiB库使用指北

TSLiB是一个为深度学习时间序列分析量身打造的开源仓库。它提供了多种深度时间序列模型的统一实现&#xff0c;方便研究人员评估现有模型或开发定制模型。TSLiB涵盖了长时预测&#xff08;Long-term forecasting&#xff09;、短时预测&#xff08;Short-term forecasting&…

【力扣】划分为k个相等的子集

&#x1f525;博客主页&#xff1a; 我要成为C领域大神&#x1f3a5;系列专栏&#xff1a;【C核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 给定一个整数数组 …

Learn OpenGL In Qt之系列简介

竹杖芒鞋轻胜马,谁怕?一蓑烟雨任平生~ 个人主页&#xff1a; rainInSunny | 个人专栏&#xff1a; C那些事儿、 Learn OpenGL In Qt 文章目录 传送门写在前面为什么是OpenGL和Qt能学到什么能做点什么国漫女神炫酷进度冷酷机器人 传送门 待更新 写在前面 本博客系列将带领读…

Vue——初识vue

目录 1.浏览器控制台报错 2.Vue入门 3.Vue模版语法 4.数据绑定 5.el与data的两种写法 总结 本系列属于纯干货系列&#xff0c;我们也不多说&#xff0c;直接上干货。 1.浏览器控制台报错 GET http://127.0.0.1:5500/favicon.ico 404 (Not Found) 具体如下图 这是为什么…

自己动手写CPU_step5_移动指令

移动操作指令 define EXE_MOVN 6b001011 //不等于0转移 if rt ! 0 then rs -> rd define EXE_MOVZ 6b001010 //等于0转移 if rt 0 then rs -> rd define EXE_MFHI 6b010000 // hi -> rd define EXE_MFLO 6b010010 // lo…