【图论刷题-3】力扣 733. 图像渲染

2024-01-13 04:08

本文主要是介绍【图论刷题-3】力扣 733. 图像渲染,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

图论刷题

  1. 机器人的运动范围
  2. 矩阵中的路径
  3. 图像渲染
  4. 水位上升的泳池中游泳

733. 图像渲染

力扣原题 地址

难度与标签

中等难度

  • 广度优先搜索(BFS)
  • 深度优先搜索(DFS)

题目描述

有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间。

给你一个坐标 (sr, sc) 表示图像渲染开始的像素值(行 ,列)和一个新的颜色值 newColor,让你重新上色这幅图像。

为了完成上色工作,从初始坐标开始,记录初始坐标的上下左右四个方向上像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应四个方向上像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为新的颜色值。

最后返回经过上色渲染后的图像。

示例 1:

输入: 
image = [[1,1,1],[1,1,0],[1,0,1]]
sr = 1, sc = 1, newColor = 2
输出: [[2,2,2],[2,2,0],[2,0,1]]
解析: 
在图像的正中间,(坐标(sr,sc)=(1,1)),
在路径上所有符合条件的像素点的颜色都被更改成2。
注意,右下角的像素没有更改为2,
因为它不是在上下左右四个方向上与初始点相连的像素点。

注意:

  • imageimage[0] 的长度在范围 [1, 50] 内。
  • 给出的初始点将满足 0 <= sr < image.length0 <= sc < image[0].length
  • image[i][j]newColor 表示的颜色值在范围 [0, 65535] 内。

题目分析

首先理解这个用例输入输出:

对于输入的二维数组:

111
110
101

其中开始位置为 (1,1) 新的颜色为 2

所以整张图的遍历就从表中的 1 开始,并且需要从这个点上下左右进行遍历,如果满足特定条件,就进行 “渲染”:遍历到的点与初始点的颜色相同,即代表颜色的值相同。

输出结果为:

222
220
201

例2 为了确保自己已经理解了题目意思,不妨修改输入然后提交查看输出。

151
110
301

其中开始位置为 (1,1) 新的颜色为 2

输出结果为:

251
220
301

因为 35 不满足 渲染 条件,而 右边的两个 1 又因为隔离不能被 渲染.

在理解题意以后就方便写代码了,广度优先遍历与深度优先遍历都能解决问题,并且难易程度近似。这里直接摘录 官方解答 ,注意是考虑到代码简洁规范。

解题代码1——广度优先遍历(BFS)

class Solution {
public:// 成对出现,表示上下左右方向const int dx[4] = {1, 0, 0, -1};const int dy[4] = {0, 1, -1, 0};vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {// 当前的颜色;int currColor = image[sr][sc];// 如果已染色if (currColor == newColor) return image;int n = image.size(), m = image[0].size();// 注意队列的数据类型是 pair queue<pair<int, int>> que;que.emplace(sr, sc);image[sr][sc] = newColor;while (!que.empty()) {int x = que.front().first, y = que.front().second;que.pop();// 四个方向遍历for (int i = 0; i < 4; i++) {int mx = x + dx[i], my = y + dy[i];// 边界判定if (mx >= 0 && mx < n && my >= 0 && my < m && image[mx][my] == currColor) {que.emplace(mx, my);image[mx][my] = newColor;}}}return image;}
};

复杂度分析

  • 时间复杂度: O ( n × m ) O(n\times m) O(n×m) ,其中 n n n m m m 分别是二维数组的行数和列数。最坏情况下需要遍历所有的方格一次。
  • 空间复杂度: O ( n × m ) O(n\times m) O(n×m) ,其中 n n n m m m 分别是二维数组的行数和列数。主要为队列的开销。

解题代码2——深度优先遍历(DFS)

DFS 用到了递归,但是总体思路也比较简单,一定要重点关注递归的终止条件。

class Solution {
public:const int dx[4] = {1, 0, 0, -1};const int dy[4] = {0, 1, -1, 0};void dfs(vector<vector<int>>& image, int x, int y, int color, int newColor) {// 如果颜色等于初始颜色就可以渲染// 并且四个方向进行检测,渲染if (image[x][y] == color) {image[x][y] = newColor;for (int i = 0; i < 4; i++) {int mx = x + dx[i], my = y + dy[i];// 边界判断if (mx >= 0 && mx < image.size() && my >= 0 && my < image[0].size()) {dfs(image, mx, my, color, newColor);}}}}vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {int currColor = image[sr][sc];if (currColor != newColor) {dfs(image, sr, sc, currColor, newColor);}return image;}
};

复杂度分析

  • 时间复杂度: O ( n × m ) O(n\times m) O(n×m) ,其中 n n n m m m 分别是二维数组的行数和列数。最坏情况下需要遍历所有的方格一次。
  • 空间复杂度: O ( n × m ) O(n\times m) O(n×m) ,其中 n n n m m m 分别是二维数组的行数和列数。主要为队列的开销。

复习一下 BFS 和 DFS

以下内容摘录自《数据结构(C 语言版)》电子档

在这里插入图片描述

BFS

广度优先搜索(Breadth First Search, BFS)遍历类似于树的 按层次遍历 的过程。

广度优先搜索遍历的过程如下。

(1) 从图中某个顶点 v v v 出发,访问 v v v

(2) 依次访问 v v v 的各个未曾访问过的邻接点。

(3) 分别从这些邻接点出发依次访问它们的邻接点, 并使 “先被访问的顶点的邻接点“ 先于 ”后被访问的顶点的邻接点” 被访问。重复步骤(3), 直至图中所有已被访问的顶点的邻接点都被访间到。

DFS

DFS (DepthFirst Search) 遍历类似于树的 先序遍历,是树的先序遍历的推广。

对于一个连通图,深度优先搜索遍历的过程如下。

(1) 从图中某个顶点 v v v 出发, 访问 v v v

(2) 找出刚访问过的顶点的第一个未被访问的邻接点, 访问该顶点。 以该顶点为新顶点,重复此步骤, 直至刚访问过的顶点没有未被访问的邻接点为止。

(3) 返回前一个访问过的且仍有未被访问的邻接点的顶点,找出该顶点的下一个未被访问的邻接点, 访问该顶点。

(4) 重复步骤 (2) 和 (3), 直至图中所有顶点都被访问过,搜索结束。

总结

刷这道题的主要目标是通过简单的题回顾一下 DFS 和 BFS 的基本思想以及如何结合实际应用(比如说遍历的时候的条件等)。相对于前面两道题这个应该更简单,更方便以最快的速度回顾一下以前的知识。

Smileyan
2021.8.15 23:16

这篇关于【图论刷题-3】力扣 733. 图像渲染的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/600195

相关文章

Python中OpenCV与Matplotlib的图像操作入门指南

《Python中OpenCV与Matplotlib的图像操作入门指南》:本文主要介绍Python中OpenCV与Matplotlib的图像操作指南,本文通过实例代码给大家介绍的非常详细,对大家的学... 目录一、环境准备二、图像的基本操作1. 图像读取、显示与保存 使用OpenCV操作2. 像素级操作3.

C/C++的OpenCV 进行图像梯度提取的几种实现

《C/C++的OpenCV进行图像梯度提取的几种实现》本文主要介绍了C/C++的OpenCV进行图像梯度提取的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录预www.chinasem.cn备知识1. 图像加载与预处理2. Sobel 算子计算 X 和 Y

c/c++的opencv图像金字塔缩放实现

《c/c++的opencv图像金字塔缩放实现》本文主要介绍了c/c++的opencv图像金字塔缩放实现,通过对原始图像进行连续的下采样或上采样操作,生成一系列不同分辨率的图像,具有一定的参考价值,感兴... 目录图像金字塔简介图像下采样 (cv::pyrDown)图像上采样 (cv::pyrUp)C++ O

Python Selenium动态渲染页面和抓取的使用指南

《PythonSelenium动态渲染页面和抓取的使用指南》在Web数据采集领域,动态渲染页面已成为现代网站的主流形式,本文将从技术原理,环境配置,核心功能系统讲解Selenium在Python动态... 目录一、Selenium技术架构解析二、环境搭建与基础配置1. 组件安装2. 驱动配置3. 基础操作模

Python+wxPython构建图像编辑器

《Python+wxPython构建图像编辑器》图像编辑应用是学习GUI编程和图像处理的绝佳项目,本教程中,我们将使用wxPython,一个跨平台的PythonGUI工具包,构建一个简单的... 目录引言环境设置创建主窗口加载和显示图像实现绘制工具矩形绘制箭头绘制文字绘制临时绘制处理缩放和旋转缩放旋转保存编

python+OpenCV反投影图像的实现示例详解

《python+OpenCV反投影图像的实现示例详解》:本文主要介绍python+OpenCV反投影图像的实现示例详解,本文通过实例代码图文并茂的形式给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一、前言二、什么是反投影图像三、反投影图像的概念四、反向投影的工作原理一、利用反向投影backproj

使用Python实现图像LBP特征提取的操作方法

《使用Python实现图像LBP特征提取的操作方法》LBP特征叫做局部二值模式,常用于纹理特征提取,并在纹理分类中具有较强的区分能力,本文给大家介绍了如何使用Python实现图像LBP特征提取的操作方... 目录一、LBP特征介绍二、LBP特征描述三、一些改进版本的LBP1.圆形LBP算子2.旋转不变的LB

OpenCV图像形态学的实现

《OpenCV图像形态学的实现》本文主要介绍了OpenCV图像形态学的实现,包括腐蚀、膨胀、开运算、闭运算、梯度运算、顶帽运算和黑帽运算,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起... 目录一、图像形态学简介二、腐蚀(Erosion)1. 原理2. OpenCV 实现三、膨胀China编程(

使用Python开发一个图像标注与OCR识别工具

《使用Python开发一个图像标注与OCR识别工具》:本文主要介绍一个使用Python开发的工具,允许用户在图像上进行矩形标注,使用OCR对标注区域进行文本识别,并将结果保存为Excel文件,感兴... 目录项目简介1. 图像加载与显示2. 矩形标注3. OCR识别4. 标注的保存与加载5. 裁剪与重置图像

详解如何在React中执行条件渲染

《详解如何在React中执行条件渲染》在现代Web开发中,React作为一种流行的JavaScript库,为开发者提供了一种高效构建用户界面的方式,条件渲染是React中的一个关键概念,本文将深入探讨... 目录引言什么是条件渲染?基础示例使用逻辑与运算符(&&)使用条件语句列表中的条件渲染总结引言在现代