【LeetCode】652 and 1365(二叉树基础思想之递归算法3)

该题为我们对二叉树遍历框架使用中明确【什么时候做】提供学习参考。
具体有关二叉树遍历框架可参考二叉树遍历框架

652. 寻找重复的子树

在这里插入图片描述
在这里插入图片描述
解法:递归+遍历框架
依旧是同样的求解思路,明确「该做什么」和「什么时候做」:

  • 「该做什么」对于每个节点,需要描述以其为根节点的树内容。
  • 「什么时候做」先得到左子树的描述,再得到右子树的描述,再加上根节点。因此是后序遍历。

在这里,对子树的描述可以采用二叉树的序列化表示,即利用二叉树的前序/中序/后序遍历结果来描述二叉树的结构。我们用非数字的特殊符#表示空指针,并且用字符,分隔每个二叉树节点值,这属于序列化二叉树的套路了。例如,对于上例中的:
在这里插入图片描述
我们可以表示为 ##4,#,2 (后序遍历)。
另外该题需要对重复结构进行判断,这需要我们借助一个数据结构来对已有结构进行存储,这里可以采用哈希表或者集合。但对于后者会出现出现次数>2的结构会被重复统计的情况,因此我们采用哈希表来存储。具体代码如下:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def findDuplicateSubtrees(self, root: Optional[TreeNode]) -> List[Optional[TreeNode]]:
        res = {}
        result = []
        def search(node):
            if not node:
                return "#"
            left = search(node.left)
            right = search(node.right)
            # 采用","来分隔每个二叉树结构的节点描述值,
            # 具体可通过将[10,2,22,1,12,1,1]作为输入示例,并打印中间结果来理解。
            tree = left + "," + right + "," + str(node.val)
            if tree in res:
                if res[tree] == 1:
                    result.append(node)
                res[tree] += 1
            else:
                res[tree] = 1
            return tree
        search(root)
        return result

1365. 有多少数小于当前数字的数字

在这里插入图片描述
解法:计数排序
注意到数组元素的值域为 [0,100],所以可以考虑建立一个频次数组 cnt,cnt[i] 表示数字 i 出现的次数。那么对于数字 i 而言,小于它的数目就为 cnt[0…i-1] 的总和。cnt[0…i-1]的总和可以用前缀和来求解。

class Solution:
    def smallerNumbersThanCurrent(self, nums: List[int]) -> List[int]:
        cnt = [0] * 101
        for num in nums:
            cnt[num] += 1
        for i in range(1, len(cnt)):
            cnt[i] += cnt[i-1]
        result = []
        for num in nums:
        	# 需要注意边界值,对于=0,没有比其更小的数字
            if num-1 < 0:
                result.append(0)
            else:
                result.append(cnt[num-1])
        return result
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值