秋招算法备战第37天 | 738.单调递增的数字、968.监控二叉树、贪心算法总结

738. 单调递增的数字 - 力扣(LeetCode)

这个问题是关于找到一个小于或等于给定数字n的最大单调递增数字。

我们可以将数字n转换为字符数组,然后从左到右扫描,寻找第一个违反单调递增条件的位置。一旦找到这样的位置,我们将该位置上的数字减一,并将其右侧的所有数字设置为9,以使得整个数字尽可能大。

然而,这个策略可能会导致左侧的一些数字违反单调递增的条件,因此我们需要从违反位置开始向左扫描,以确保整个数字仍然是单调递增的。

以下是解决问题的Python代码:

python 复制代码
def monotoneIncreasingDigits(n: int) -> int:
    digits = list(str(n))
    n = len(digits)
    pos = n  # 用来记录第一个违反单调递增条件的位置

    # 扫描从左到右找到第一个违反单调递增条件的位置
    for i in range(n - 1, 0, -1):
        if digits[i] < digits[i - 1]:
            pos = i
            digits[i - 1] = str(int(digits[i - 1]) - 1)

    # 将pos右侧的所有数字设置为9
    for i in range(pos, n):
        digits[i] = '9'

    return int(''.join(digits))

我们可以用给定的示例来测试这个函数:

python 复制代码
print(monotoneIncreasingDigits(10))  # 输出: 9
print(monotoneIncreasingDigits(1234))  # 输出: 1234
print(monotoneIncreasingDigits(332))  # 输出: 299

注:这题的关键还是通过样例观察规律,找到贪心的解法

968. 监控二叉树 - 力扣(LeetCode)

使用贪心算法来解决此问题的关键思想是自底向上遍历二叉树,并尽可能地在没有摄像头的父节点上放置摄像头。以下是具体步骤和实现:

  1. 我们可以自底向上遍历二叉树,使用后序遍历。
  2. 为了记录每个节点的状态,我们可以使用三个常量表示:0表示未监视,1表示有摄像头,2表示被监视。
  3. 如果任何子节点未监视,则在当前节点放置摄像头。
  4. 如果任何子节点有摄像头,则当前节点被监视。
  5. 如果所有子节点都被监视,则当前节点未监视。
  6. 我们需要确保根节点被监视,所以如果根节点未监视,则增加一个摄像头。

以下是Python代码实现:

python 复制代码
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def minCameraCover(root: TreeNode) -> int:
    NOT_MONITORED, MONITORED_WITHOUT_CAM, MONITORED_WITH_CAM = 0, 1, 2
    cameras = 0

    # 后序遍历函数
    def dfs(node):
        nonlocal cameras
        if not node:
            return MONITORED_WITHOUT_CAM

        left = dfs(node.left)
        right = dfs(node.right)

        if left == NOT_MONITORED or right == NOT_MONITORED:
            cameras += 1
            return MONITORED_WITH_CAM

        if left == MONITORED_WITH_CAM or right == MONITORED_WITH_CAM:
            return MONITORED_WITHOUT_CAM

        return NOT_MONITORED

    # 如果根节点未监视,则增加一个摄像头
    if dfs(root) == NOT_MONITORED:
        cameras += 1

    return cameras

可以使用上面给出的示例来测试该函数,结果应与之前相同。这种贪心策略确保了在满足所有约束的情况下使用的摄像头数量最少。

贪心算法总结

如果找出局部最优并可以推出全局最优,就是贪心,如果局部最优都没找出来,就不是贪心,可能是单纯的模拟。

在做贪心题的过程中,如果再来一个数据证明,其实没有必要,手动模拟一下,如果找不出反例,就试试贪心。面试中,代码写出来跑过测试用例即可,或者自己能自圆其说理由就行了

星友总结的思维导图如下

相关推荐
花开富贵ii1 小时前
代码随想录算法训练营四十三天|图论part01
java·数据结构·算法·深度优先·图论
weixin_307779131 小时前
AWS Lambda解压缩S3 ZIP文件流程
python·算法·云计算·aws
code小毛孩2 小时前
leetcode hot100数组:缺失的第一个正数
数据结构·算法·leetcode
legendary_bruce8 小时前
【22-决策树】
算法·决策树·机器学习
max50060010 小时前
基于桥梁三维模型的无人机检测路径规划系统设计与实现
前端·javascript·python·算法·无人机·easyui
快去睡觉~12 小时前
力扣400:第N位数字
数据结构·算法·leetcode
qqxhb13 小时前
零基础数据结构与算法——第七章:算法实践与工程应用-搜索引擎
算法·搜索引擎·tf-idf·倒排索引·pagerank·算法库
gzzeason14 小时前
LeetCode Hot100:递归穿透值传递问题
算法·leetcode·职场和发展
汤永红14 小时前
week1-[循环嵌套]画正方形
数据结构·c++·算法
pusue_the_sun14 小时前
数据结构——顺序表&&单链表oj详解
c语言·数据结构·算法·链表·顺序表