Grind75第9天 | 733.图像渲染、542.01矩阵、1235.规划兼职工作

733.图像渲染

题目链接:https://leetcode.com/problems/flood-fill

解法:

可以用深度优先搜索和广度优先搜索。

深度优先搜索。每次搜索到一个方格时,如果其与初始位置的方格颜色相同,就将该方格的染色,然后继续对其上下左右4个方位进行染色;如果不相同,则进行返回。

因为初始位置的颜色会被修改,所以我们需要保存初始位置的颜色,以便于之后的更新操作。

广度优先搜索。使用队列,每次搜索到一个方格时,如果其与初始位置的方格颜色相同,就将该方格的染色,并把上下左右4个方位加入队列。遵循先进先出,而不是把某个位置深挖到底。

需要注意的是,如果算法开始之前,当前的颜色已经和需要染的颜色相同了,就直接返回,因为如果相邻点和当前颜色相同,那么就和需要染的颜色相同,不需要再染,如果相邻点和当前颜色不相同,那么没法染。所以就是不用操作了。

参考题解:BFS+DFS

边界条件:当前的颜色和需要染的颜色相同。

时间复杂度:O(n×m)

空间复杂度:O(n×m)

# DFS
class Solution:def floodFill(self, image: List[List[int]], sr: int, sc: int, color: int) -> List[List[int]]:# 需要染成的颜色self.new_color = color# 初始颜色self.old_color = image[sr][sc]self.dfs(image, sr, sc)return imagedef dfs(self, image, sr, sc):if sr < 0 or sc < 0 or sr >= len(image) or sc >= len(image[0]):return# 如果相邻的像素不相同,则返回if image[sr][sc] != self.old_color:return# 如果已经被染色,则返回if image[sr][sc] == self.new_color:returnimage[sr][sc] = self.new_colordirections = [(-1, 0),(1,0),(0, -1),(0, 1)]for d in directions:self.dfs(image, sr+d[0], sc+d[1])
# BFS
class Solution:def floodFill(self, image: List[List[int]], sr: int, sc: int, color: int) -> List[List[int]]:# 这个条件如果不加,那么下面可能无限循环# 如果当前的颜色就是要染的颜色,那么不同的颜色没法染,相同的颜色不用染,所以不用操作if image[sr][sc] == color:return imageque = deque([(sr,sc)])old_color = image[sr][sc]image[sr][sc] = colordirections = [(-1,0), (1,0), (0,-1), (0,1)]m, n = len(image), len(image[0])while que:for i in range(len(que)):r, c = que.popleft()for d in directions:new_r, new_c = r+d[0], c+d[1]if 0 <= new_r < m and 0 <= new_c < n and image[new_r][new_c] == old_color:que.append((new_r, new_c))image[new_r][new_c] = colorreturn image

542.01矩阵

题目链接:https://leetcode.com/problems/01-matrix

解法:

这个题动态规划的写法看着很复杂,广度优先搜索的思路非常优雅简洁。

假设矩阵中一共有两个0,其他都是1,如下图的左图所示。首先初始化所有点的距离为0,然后把值为0的这两个点加入队列。接着把0周围的1都计算距离,距离都是1,同时把这些值为1的点加入队列。到弹出值为1的点时,它相邻的且未访问过的点(值也是1),距离都为2,即 dist[i][j] + 1。

这就是大致的思路,从下图也可以看出。

参考题解:BFS

边界条件:无

时间复杂度:O(mn)

空间复杂度:O(mn)

class Solution:def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:m,n = len(mat), len(mat[0])dist = [[0]*n for _ in range(m)]zero_pos = [(i,j) for i in range(m) for j in range(n) if mat[i][j] == 0]q = deque(zero_pos)visited = set(zero_pos)directions = [(-1,0), (1,0), (0,-1), (0,1)]while q:i, j = q.popleft()for d in directions:new_i, new_j = i+d[0], j+d[1]# 第一轮先把0附近的1都计算距离# 第二轮把1附近的1都计算距离if 0 <= new_i < m and 0 <= new_j < n and (new_i, new_j) not in visited:dist[new_i][new_j] = dist[i][j] + 1q.append((new_i, new_j))visited.add((new_i, new_j))return dist

1235.规划兼职工作

题目链接:https://leetcode.com/problems/maximum-profit-in-job-scheduling

解法:

动态规划+二分查找。这个题的实现细节有些比较坑的地方,我下面总结一下。

1. dp[i]的定义:使用 dp[i] 表示前 i 份兼职工作可以获得的最大报酬,即区间 [0,i−1]的所有兼职工作可以获得的最大报酬。这意味着 dp 是 1 indexed的,而工作的三个列表 starttime, endtime, profit 都是 0 indexed。dp[1] 对应到 starttime[0], endtime[0], profit[0]。

初始时 dp[0]=0=0,表示没有兼职工作时报酬为 0。

2.转移方程:对于 i>0,根据第 i (对应dp中的i,profit中的i-1)份兼职工作是否被选择,我们有以下转移方程:

dp[i] = max(dp[i-1], dp[k] + profit[i-1])

因此我们需要找到小于等于第 i 份兼职的startTime的endTime。这里非常危险,因为存在这种情况:endtime的列表为[1,2,3,3,4],而第1份兼职的startTime=3,那么我们注意到endtime列表中有两个满足条件的3,而我们需要的是第2个而不是第1个。那么怎么处理呢?

我们转为找到第一个大于startTime的endTime,它的下标为k,那么我们真正需要的就是k-1,对应到dp就是dp[k]。

这就是为什么很多题解用了 python 的bisect_right 函数得到第一个大于startTime的索引k,然后直接使用dp[k]的原因。这里其实省略了过程:由k得到k-1,再因为profit[i-1]对应dp[i],所以k-1对应dp[k]。说得也没有很严谨,但就是这个思路。

3. 二分查找的实现:这里二分查找的实现和leetcode的二分查找不一样,leetcode的二分查找,列表中的数是唯一的,不存在重复。但是这个题存在重复的case,比如上面举的例子 [1,2,3,3,4],从中寻找小于等于3的数的索引。如果按照 nums[mid] == 3,return mid,那么得到的就是第1个3的索引,而我们实际想要的是第2个3的索引。

因此二分查找的实现就是同 bisect_right 的功能,返回第一个大于target的数的索引。

参考题解:动态规划+二分查找

边界条件:无

时间复杂度:O(nlogn),排序的复杂度是 O(nlogn),遍历+二分查找的复杂度合计是O(nlogn)

空间复杂度:O(n)

class Solution:def jobScheduling(self, startTime, endTime, profit):n = len(startTime)# 按照endTime升序排列jobs = sorted(zip(startTime, endTime, profit), key=lambda p: p[1])# dp[i] 是 1 indexed,dp[0]表示无兼职,dp[1]表示1份兼职的最大报酬# 但 jobs是 0 indexed,dp[1]对应到jobs[0], dp[2]对应到[0,1]左闭右闭区间的jobs,所以 dp[i] 表示前i份兼职(对应job中的i-1)的最大报酬dp = [0] * (n + 1)for i in range(1, n + 1):k = self.binary_search(jobs, jobs[i - 1][0], i-1)dp[i] = max(dp[i - 1], dp[k] + jobs[i - 1][2])return dp[n]def binary_search(self, arr, x, hi):lo = 0while lo <= hi:mid = lo + (hi - lo) // 2if arr[mid][1] <= x:lo = mid + 1else:hi = mid - 1return lo  # 返回第一个大于x的值的索引

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI嵌入式K210项目(11)-SPI Flash读写

文章目录 前言一、K210的SPI二、Flash介绍三、实验过程总结 前言 这一章我们来学习下SPI及其应用&#xff0c;SPI 是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;由于其高速、同步和简单的特性&#xff0c;被广泛应用于各种微控制器和外围设备之间的通…

统计学R语言实验7 方差分析

统计学R语言实验7 方差分析 一、实验目的 1. 掌握理解方差分析的相关概念。 2. 掌握理解方差分析的相关方法。 3. 熟悉R语言等语言的集成开发环境。 二、实验分析与内容 完成教材P117的第4题 本题采用单因素方差分析来解题&#xff1a; &#xff08;1&#xff09;分析三…

2023年全球软件架构师峰会(ArchSummit深圳站):核心内容与学习收获(附大会核心PPT下载)

本次峰会是一次重要的技术盛会&#xff0c;旨在为全球软件架构师提供一个交流和学习的平台。本次峰会聚焦于软件架构的最新趋势、最佳实践和技术创新&#xff0c;吸引了来自世界各地的软件架构师、技术专家和企业领袖。 在峰会中&#xff0c;与会者可以了解到数字化、AIGC、To…

电梯节能落座-智慧停车场️,电梯不仅可载人也可以载汽车!

电梯不仅可载人也可以载汽车哦&#xff01; 在北京市丰台区&#xff0c;有这么一个智慧停车场&#x1f17f;️ &#xff0c;共298个停车位&#xff0c;全部智能一体化&#xff0c;简直是“豪华” “智能” 的象征。 523能源&#xff1a;小伍&#xff0c;你跑题了... 小伍&am…

【牛客周赛Round 27】题目讲解

题目一 小红的二进制删数字&#xff1a; 小红拿到了一个二进制字符串 s&#xff0c;她可以删掉其中的一些字符&#xff0c;使得最终该字符串为一个2的幂&#xff08;即可以表示为 2^k 形式的数&#xff09;。小红想知道&#xff0c;自己最少删几个字符可以达成&#xff1f;请你…

【GAMES101】Lecture 07 着色(shading)

目录 着色 Blinn-Phong反射模型 漫反射 光衰减 着色 这个着色&#xff08;shading&#xff09;就是将不同的材质应用到不同的物体上&#xff0c;像一个物体&#xff0c;它可以是木头的、金属的、塑料的…… Blinn-Phong反射模型 我们来看一个简单的着色模型&#xff0c;…

大文件的断点续传如何实现

断点续传 断点续传是一种数据恢复技术&#xff0c;主要用于在读取或发送数据时&#xff0c;因为网络问题、磁盘问题等原因导致数据传输中断。断点续传技术允许你在已经传输的数据基础上继续传输&#xff0c;从而节省数据传输时间。 断点续传通常用于文件传输过程中&#xff0c;…

C语言基本概念——正确理解C,不要被错误的题目误导

在进行C语言训练或做题时&#xff0c;我们可能会遇到一些看似简单但实则错误的题目。这些题目可能会误导我们对C语言基本概念的认识。因此&#xff0c;正确理解C语言并辨别题目中的错误至关重要。下面&#xff0c;举例说明题目错在哪。 1. 写出下列程序的运行结果。 #include…

vue3自定义按钮点击变颜色(切换)

实现效果图&#xff1a; 默认选中第一个按钮&#xff0c;未选中按钮为粉色&#xff0c;点击时颜色变为红色 利用动态类名&#xff0c;当定义isChange数值和下标index相同时&#xff0c;赋予act类名&#xff0c;实现变色效果 <template><view class"page"&g…

Find -name详解

Linux find命令的基本语法如下&#xff1a; find [path] [expression] path&#xff1a;要查找的目录路径。 expression&#xff1a;查找表达式&#xff0c;指定要查找的文件类型、名称、大小等条件 例子&#xff1a;find /etc -name passwd 这个表达式&#xff0c;指定条件为…

进阶Docker4:网桥模式、主机模式与自定义网络

目录 网络相关 子网掩码 网关 规则 docke网络配置 bridge模式 host模式 创建自定义网络(自定义IP) 网络相关 IP 子网掩码 网关 DNS 端口号 子网掩码 互联网是由许多小型网络构成的&#xff0c;每个网络上都有许多主机&#xff0c;这样便构成了一个有层次的结构。 IP 地…

【踩坑日志】SpringBoot读取nacos配置信息并提取信息中的IP地址(配置属性解析异常+排错记录)

缘起 &#xff1a;项目需读取nacos中动态的TDengine数据库连接信息并提取IP&#xff0c;一个并不复杂的操作&#xff0c;但作为一个nacos知识浅薄的菜鸡&#xff0c;我愣是捯饬了几个小时……惭愧惭愧…… 异常代码 Data Component public class TaosLink { // Value("…