秋招算法备战第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

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

贪心算法总结

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

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

星友总结的思维导图如下

相关推荐
小静AI工程实验室8 分钟前
RSA 算法详解:从模幂原理到 OAEP 加密、PSS 签名与 Python 实验
python·算法
xzal1215 分钟前
GESP Python笔记
笔记·python·算法
wzdark17 分钟前
算法中的记忆化思想与重复子问题优化4
算法
Discipline102942 分钟前
流水线运行是否正随时间变得更加集中?
算法
lzhdim1 小时前
C#不为人知的10个魔法特性:资深开发者也会震惊的底层奥秘
java·前端·javascript·算法·c#
weixin_307779131 小时前
C++代码实现MATLAB中的pade函数功能
开发语言·c++·算法·matlab
smj2302_796826521 小时前
解决leetcode第4064题至多一次取反能被k整除的最长子数组II
python·算法·leetcode
AIGC小尼1 小时前
ACE-Step-1.5 本地 AI 音乐模型实战|text2music 歌词转人声,部署脚本、参数调优与排坑全记录
人工智能·算法·comfyui·ai漫剧
YOLO数据集集合1 小时前
树木检测数据集 | 树木检测 树种分类 航拍林业 森林监测9131期
人工智能·算法·机器学习·分类·数据挖掘·林业·树种分类
青山木1 小时前
Hot 100 --- 下一个排列
java·数据结构·算法·leetcode