2021-12-08 每日打卡:腾讯精选50题
写在前面
“这些事儿在熟练之后,也许就像喝口水一样平淡,但却能给初学者带来巨大的快乐,我一直觉得,能否始终保持如初学者般的热情、专注,决定了在做某件事时能走多远,能做多好。” 该系列文章由python编写,遵循LeetBook 列表/腾讯的刷题顺序,所有代码已通过。每日3道,随缘剖析,希望风雨无阻,作为勉励自己坚持刷题的记录。
104. 二叉树的最大深度
- DFS非递归:
class Solution:
def maxDepth(self, root: TreeNode) -> int:
if not root:return 0
stack, res = [(root,1)],1
while(stack):
tmp,depth = stack.pop()
res = max(depth, res)
if (tmp.right):
stack.append((tmp.right,depth+1))
if (tmp.left):
stack.append((tmp.left,depth+1))
return res
- 递归DFS:
class Solution:
def maxDepth(self, root):
if root is None:
return 0
else:
left_height = self.maxDepth(root.left)
right_height = self.maxDepth(root.right)
return max(left_height, right_height) + 1
124. 二叉树中的最大路径和
- 【第一遍未做出】关键在于我们并不能按照路径的样子(就是从叶子结点开始递归),而是从根节点开始,所以大胆推测一个递归表达式!
一个子树内部的最大路径和 = 左子树提供的最大路径和 + 根节点值 + 右子树提供
那么负数怎么办?我们把负结点的贡献视为0,不走就好啦,毕竟最后只需要最短路径的数,而不是具体结点。但考虑下面这颗树[-3],当其作为子树时return的贡献应该为0,而作为单独的树时,应该返回-3。也就说明,返回值和贡献值应该分开计算! - 所以树的问题一般确定框架后,就只需要
根据题意确定具体的表达式!
class Solution:
def maxPathSum(self, root: Optional[TreeNode]) -> int:
self.res = -float(inf)
# 递归的过程中实际上有对每个节点进行考察,使用成员变量保存
def helper(root):
if not root:
return 0
left = helper(root.left)
right = helper(root.right)
# 贡献值有四种情况:
# 左边走到当前结点不再走,右边走到当前节点不再走,只走当前节点,全走
self.res = max(self.res, max(left, right, 0, left + right) + root.val)
# 返回值:
# 因为不能有回路,所以我们选择最大的一条路走上来/仅有自身
return max(left, right, 0) + root.val
helper(root)
return self.res
230. 二叉搜索树中第K小的元素
- 中序遍历!使用递归:
class Solution:
def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
self.visited = 0
def medvisit(root):
l, r = 0, 0
if not root:
return
if (root.left):
l = medvisit(root.left)
self.visited+=1
if self.visited==k:
return root.val
if (root.right):
r = medvisit(root.right)
return l if l else r
return medvisit(root)
- 中序遍历!非递归:
class Solution:
def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
visited,stack = 0,[]
while(root or stack):
while root:
stack.append(root)
root =root.left
root = stack.pop()
visited+=1
if (visited==k): return root.val
root = root.right
return -1