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

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

贪心算法总结

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

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

星友总结的思维导图如下

相关推荐
WHS-_-20222 小时前
A Density Clustering-Based CFAR Algorithm for Ship Detection in SAR Images
算法·5g
Miraitowa_cheems5 小时前
LeetCode算法日记 - Day 68: 猜数字大小II、矩阵中的最长递增路径
数据结构·算法·leetcode·职场和发展·贪心算法·矩阵·深度优先
灵感__idea7 小时前
Hello 算法:让前端人真正理解算法
前端·javascript·算法
学习2年半7 小时前
小米笔试题:一元一次方程求解
算法
MATLAB代码顾问7 小时前
MATLAB绘制多种混沌系统
人工智能·算法·matlab
极客BIM工作室8 小时前
演化搜索与群集智能:五种经典算法探秘
人工智能·算法·机器学习
qq_574656258 小时前
java-代码随想录第66天|Floyd 算法、A * 算法精讲 (A star算法)
java·算法·leetcode·图论
金融街小单纯9 小时前
从蓝军建设中学习颠覆性质疑思维
人工智能·算法·机器学习
少许极端10 小时前
算法奇妙屋(五)-链表
数据结构·算法·链表
XISHI_TIANLAN10 小时前
【多模态学习】Q&A6: 什么是MOE架构?Router Z Loss函数是指什么?负载均衡损失(Load Balancing Loss)又是什么?
学习·算法·语言模型