1.56. 合并区间
class Solution(object):
def merge(self, intervals):
"""
:type intervals: List[List[int]]
:rtype: List[List[int]]
"""
res = []
#按照左边界排序
intervals.sort(key = lambda x:x[0])
#遍历
for i in range(1, len(intervals)):
if intervals[i][0] > intervals[i - 1][1]:
#不重叠
res.append(intervals[i - 1])
else:
#重叠
intervals[i][0] = min(intervals[i - 1][0], intervals[i][0])
intervals[i][1] = max(intervals[i - 1][1], intervals[i][1])
#记录最后一个区间
res.append(intervals[-1])
return res
class Solution(object):
def merge(self, intervals):
"""
:type intervals: List[List[int]]
:rtype: List[List[int]]
"""
res = []
#排序
intervals.sort(key = lambda x:x[0])
#记录第一个区间
res.append(intervals[0])
for i in range(1, len(intervals)):
if intervals[i][0] <= res[-1][1]:
#重叠,更新res区间右边界
res[-1][1] = max(res[-1][1], intervals[i][1])
else:
#不重叠
res.append(intervals[i])
return res
2.738.单调递增的数字
题目链接:738.单调递增的数字
文档讲解: 代码随想录
class Solution(object):
def monotoneIncreasingDigits(self, n):
"""
:type n: int
:rtype: int
"""
#暴力解法
for i in range(n, 0, -1):
if self.check(i):
return i
return 0
def check(self, n):
max_digit = 10
while n > 0:
digit = n % 10
if max_digit >= digit:
max_digit = digit
else:
return False
n = n // 10
return True
class Solution(object):
def monotoneIncreasingDigits(self, n):
"""
:type n: int
:rtype: int
"""
#将整数转换为字符串
strNum = str(n)
#flag标记从哪位开始赋值为9
flag = len(strNum) #防止第二个for循环在flag没有被赋值的情况下执行
for i in range(len(strNum) - 1, 0, -1):
#如果当前字符比前一个字符小,则修改前一个字符
if strNum[i] < strNum[i - 1]:
#字符串不能修改
strNum = strNum[:i - 1] + str(int(strNum[i - 1]) - 1) + strNum[i:]
flag = i
#for循环赋值9
for i in range(flag, len(strNum)):
strNum = strNum[:i] + '9' + strNum[i + 1:]
return int(strNum)
3.968.监控二叉树
想要让摄像头数量最少,关键是摄像头放置的位置,需要从叶子节点后序遍历,因为叶子节点放不放摄像头省下的摄像头数量是指数阶别的,而头节点放不放摄像投就就省下一个。因此,局部最优是在叶子节点的父节点放置摄像头,所用摄像头数量最少。
接下来就是本题的难点:如何隔两个节点放置一个摄像头?
(1)此时需要状态转移,可以将节点的状态分为三种情况:无覆盖(0)、放置摄像头(1)、有覆盖(2)。
(2)递归函数的终止条件是,遇到空节点则return,那么空节点的状态应该是有覆盖。如果空节点标记为放置摄像头,那么叶子节点则是有覆盖的状态,这样的话其父节点不会放置摄像头。如果空节点标记为无覆盖,那么叶子节点需要放置摄像头。这两种情况都与期望不符。
(3)递归函数的单层逻辑:父节点接收左右孩子的状态信息。第一种情况,只要左右孩子有一个0,则父节点需要放置摄像头,为1状态。第二种情况,只要左右孩子有一个1,则父节点不用放置摄像头,为2状态。第三种情况,左右孩子都是2,则父节点是0状态。第四种情况,夫节点为头节点,且为状态0,则此时需要在头节点放置摄像头。
class Solution(object):
def minCameraCover(self, root):
"""
:type root: TreeNode
:rtype: int
"""
self.res = 0
tou = self.traversal(root)
#如果头节点为0
if tou == 0:
self.res += 1
return self.res
def traversal(self, node):
#终止条件
if not node:
return 2
#后序遍历
left = self.traversal(node.left)
right = self.traversal(node.right)
#处理中间节点
#左右孩子至少一个0
if left == 0 or right == 0:
self.res += 1
return 1
#左右孩子至少一个1
if left == 1 or right == 1:
return 2
#左右孩子都为2
if left == 2 and right == 2:
return 0
用elif精简:
class Solution(object):
def minCameraCover(self, root):
"""
:type root: TreeNode
:rtype: int
"""
self.res = 0
if self.traversal(root) == 0:
self.res += 1
return self.res
def traversal(self, node):
if not node:
return 2
left = self.traversal(node.left)
right = self.traversal(node.right)
if left == 2 and right == 2:
return 0
elif left == 0 or right == 0:
#如果出现(1,0)的组合,优先判断是否有0
self.res += 1
return 1
else:
return 2