力扣题目链接(opens new window)
给定一个非负整数 N,找出小于或等于 N 的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增。
(当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。)
示例 1:
示例 2:
示例 3:
说明: N 是在 [0, 10^9] 范围内的一个整数。
class Solution:
def monotoneIncreasingDigits(self, n: int) -> int:
digits = [int(d) for d in str(n)]
length = len(digits)
# 从右往左遍历,找到第一个不满足单调递增条件的位置
for i in range(length - 1, 0, -1):
if digits[i] < digits[i - 1]:
# 将当前位置减1
digits[i - 1] -= 1
# 将当前位置之后的所有数字都设置为9,以确保最大性
for j in range(i, length):
digits[j] = 9
# 将列表中的数字组合成整数
result = 0
for d in digits:
result = result * 10 + d
return result
# 示例
solution = Solution()
N1 = 10
N2 = 1234
N3 = 332
print(solution.monotoneIncreasingDigits(N1)) # 输出: 9
print(solution.monotoneIncreasingDigits(N2)) # 输出: 1234
print(solution.monotoneIncreasingDigits(N3)) # 输出: 299
力扣题目链接(opens new window)
给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。
计算监控树的所有节点所需的最小摄像头数量。
示例 1:
示例 2:
提示:
from typing import Optional
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def minCameraCover(self, root: Optional[TreeNode]) -> int:
# 定义三种状态
UNCOVERED, COVERED, MONITORED = 0, 1, 2
def dfs(node):
if not node:
return COVERED, 0 # 空节点不需要摄像头,且已经被覆盖
left_status, left_cameras = dfs(node.left)
right_status, right_cameras = dfs(node.right)
# 如果左右子节点有一个未被覆盖,当前节点需要放置摄像头
if left_status == UNCOVERED or right_status == UNCOVERED:
return MONITORED, left_cameras + right_cameras + 1
# 如果左右子节点有一个放置了摄像头,当前节点被覆盖
elif left_status == MONITORED or right_status == MONITORED:
return COVERED, left_cameras + right_cameras
# 其他情况,当前节点未被覆盖
else:
return UNCOVERED, left_cameras + right_cameras
status, cameras = dfs(root)
# 如果根节点未被覆盖,还需要加一个摄像头
return cameras + (status == UNCOVERED)
首先,我们定义了三个状态:
UNCOVERED
: 这意味着该节点没有被摄像头覆盖。COVERED
: 这意味着该节点被摄像头覆盖,但是该节点上没有摄像头。MONITORED
: 这意味着该节点上有一个摄像头,它可以覆盖其父节点和子节点。我们的目标是使用尽可能少的摄像头来覆盖整棵树。
下面是代码的逻辑解释:
如果当前的节点是空的,则它自动被认为是COVERED
,因为我们不需要在空节点上放摄像头。
我们递归地处理左子节点和右子节点,然后根据子节点的状态来决定当前节点的状态。
如果左子节点或右子节点中的任何一个是UNCOVERED
,这意味着当前节点必须有一个摄像头,因为只有当前节点上的摄像头才能覆盖这些UNCOVERED
的子节点。所以,我们设置当前节点的状态为MONITORED
。
如果左子节点或右子节点中的任何一个是MONITORED
,这意味着当前节点已经被覆盖了,但是不需要在上面放摄像头,因为它的子节点已经有摄像头了。所以,我们设置当前节点的状态为COVERED
。
否则,这意味着左右子节点都是COVERED
而没有摄像头。这时,当前节点是UNCOVERED
。
当整个树处理完毕后,如果根节点仍然是UNCOVERED
,我们需要再加一个摄像头。