[leetcode]508. Most Frequent Subtree Sum(Python)

题目描述

Category:Medium Tree

Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a node is defined as the sum of all the node values formed by the subtree rooted at that node (including the node itself). So what is the most frequent subtree sum value? If there is a tie, return all the values with the highest frequency in any order.
在这里插入图片描述

题目理解

给定一棵二叉树,查找最频繁出现的子树和。
节点的子树和定义为以该子节点为根的树的所有节点值之和。
最频繁出现定义为出现次数最多的树,若存在多个,以任意顺序输出即可。

解题思路

后序遍历+递归

使用递归实现后序遍历,并修改节点的值为该节点的子树和,并使用dict保存每个节点的子树和,最后遍历得到出现次数最多的子节点和。
思路借鉴:https://www.jianshu.com/p/c861361dc20f

class Solution:
    # Runtime: 48ms 71.47%  MemoryUsage: 15.6MB 100.00%
    def findFrequentTreeSum2(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        self.counter = collections.Counter()
        self.postOrderTraversal(root)
        maxValue = max(self.counter.values())
        return [key for key in self.counter.keys() if self.counter[key] == maxValue]

    def postOrderTraversal(self, node):
        if node.left:
            node.val += self.postOrderTraversal(node.left)
        if node.right:
            node.val += self.postOrderTraversal(node.right)
        self.counter[node.val] += 1
        return node.val

和我的实现思路差不多,学习修改节点值的思路(好像只能采用后序遍历)。但修改节点值减少空间占用,不适用于不可修改原树的情况。

:补充collections模块 – Counter
collections是Python内建的一个集合模块,提供了许多有用的集合类。
Counter是一个简单的计数器,例如,统计字符出现的个数:

>>> from collections import Counter
>>> c = Counter()
>>> for ch in 'programming':
...     c[ch] = c[ch] + 1
...
>>> c
Counter({'g': 2, 'm': 2, 'r': 2, 'a': 1, 'i': 1, 'o': 1, 'n': 1, 'p': 1})

Counter实际上也是dict的一个子类,上面的结果可以看出,字符’g’、‘m’、'r’各出现了两次,其他字符各出现了一次。
该部分来自:廖雪峰老师的教程
疑问:或许Counter用作字典计数时可以按照出现次数排序?

from collections import Counter
string = 'abdiejmcodfjsljdli jiejwi ppsjijds klndjknajbd jsjzljij fijpfwe fzsdzssds'
list1 = [1,1,1,1,1,1,2,3,4,4,5,1,2,9,3,4,6]
one_list=[56,7,4,23,56,9,0,56,12,3,56,34,45,5,6,56]

c = Counter()
num_counter1 = Counter()
num_counter2 = Counter()

for ch in string:
    c[ch] = c[ch] + 1

for num in list1:
    num_counter1[num] += 1

for num in one_list:
    num_counter2[num] += 1

print(c)
print(num_counter1)
print(num_counter2)

输出如下所示:

Counter({'j': 14, 'd': 8, 's': 8, 'i': 7, ' ': 6, 'l': 4, 'f': 4, 'p': 3, 'z': 3, 'e': 3, 'w': 2, 'b': 2, 'k': 2, 'a': 2, 'n': 2, 'c': 1, 'o': 1, 'm': 1})
Counter({1: 7, 4: 3, 2: 2, 3: 2, 5: 1, 6: 1, 9: 1})
Counter({56: 5, 0: 1, 34: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1, 9: 1, 12: 1, 45: 1, 23: 1})

检索发现还有一个博主,发现collections-Counter可以不改变原有顺序有序生成元素的计数字典,考虑可以通过此来获取list的有序去重复。部分例子参考了他的,贴个地址
未发现有关官方文件具体说明,该点存疑。

MyMethod

SubtreeSum函数使用递归的思想,返回每个节点的子树和,并使用字典进行记录。
主函数中借助字典和max函数得到最频繁出现的次数,依次遍历字典中各个子树和出现的次数,用res记录最频繁出现的子树和,输出即可。

class Solution:
    # Runtime: 48ms 71.47%  MemoryUsage: 16.1MB 100.00%
    def findFrequentTreeSum(self, root: TreeNode) -> List[int]:
        if root is None:
            return
        res = {}
        result_list = []
        self.SubtreeSum(root, res)
        max_num = max(res.values())
        for k, v in res.items():
            if v == max_num:
                result_list.append(k)
        return result_list

    def SubtreeSum(self, root, res):
        if root is None:
            return 0
        left = self.SubtreeSum(root.left, res)
        right = self.SubtreeSum(root.right, res)
        subsum = left + right + root.val
        if subsum in res:
            res[subsum] += 1
        else:
            res[subsum] = 1
        return subsum

Time

2020.3.20 丧丧的早上 要加油呀!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值