leetcode上两道题的思考

人工智能
• 阅读 1338

第一道题:
给定一棵二叉树,在二叉树的所有路径中找到路径上结点之和为题目给定值的子路径。路径不一定以根节点为开头,也不一定以叶节点为结尾。并且根据分析路径之间应该可以重叠。求出满足这样要求的路径的数目,并返回。

      10
     /  \
    5   -3
   / \    \
  3   2   11
 / \   \
3  -2   1

当给出以上的二叉树,并以8为路径节点和时,5->3,5->2->1,-3->11三条路径满足条件返回三。

对于根节点来讲,满足条件的路径,包括以根节点为起点的路径,以及不以根节点为起点的路径。
我们先定义一个函数,这个函数有两个节点node和sum,它的含义是,求出从node开始的,路径上各节点之和为sum的这样的路径的个数。注意是从node开始的。

result初始化为0。如果当前node的value等于sum,则将result加1。由于可能会有负数节点,因此不能立刻返回result,应该分别再递归的去计算以node的左孩子和右孩子为起点,和为sum-node.value的路径的数目。
代码如下:

    def path_num_from(self, node, sum):
        if node is None:
            return 0

        res = 0
        if node.val == sum:
            res += 1

        res += self.path_num_from(node.left, sum - node.val)
        res += self.path_num_from(node.right, sum - node.val)

        return res

之前已经提到过,本题所求的路径不仅包含以根节点为起点的路径,还包含不以根节点为起点的路径。因此我们再定义一个函数,来算出,包含根节点的路径,和不包含根节点的路径。

    def __pathSum(self, node, sum):
        if node is None:
            return 0

        return self.find_path(node, sum) + self.__pathSum(node.left, sum) + self.__pathSum(node.right, sum)

题目得解。

第二道题:
给定一个数,将其拆分为n个平方数的和,求最小的n。
例如13 = 9 + 4 13 = 9 + 1 + 1 + 1 + 1
13是9和4两个平方数的和,也是9和4个1的和(如果用重复,按出现的次数计数,1计数4次而不是1次),因为2小于5,所以返回2。

这道题不能用贪心算法求解。
当n=12时,如果用贪心算法,结果就是9+1+1+1,返回4。但是更优的解是4+4+4,返回3。

假设给出的数字为n。先建立一个set。set中存放所有的,小于n的平方数。
比如给出数字13时,set中添加1,4,9。因为16大于13,所以不添加。
以15举例。set为 1,4,9。建立一个队列。

第一轮:
15减去9,得到6。将6放入队列中。
15减去4,得到11。将11放入队列中。
15减去1,得到14,将14放入队列中。
第一轮遍历完毕。此时队列中还有6,11,14

第二轮:
6比9小,所以不能再减9。
6减4,得到2,将2放入队列中。
6减1,得到5,将5放入队列中。
11减9,得到2,将2放入队列中。
11减4,得到7,将7放入队列中。
11减1,得到10,将10放入队列中。
第二轮遍历完毕。去掉重复的数,此时队列中还有2,5,7,10。

第三轮:
2减1,得到1,将1放入队列中。
5减4,得到1,将1放入队列中。
5减1,得到4,将4放入队列中。
7减4,得到3,将3放入队列中。
7减1,得到6,将6放入队列中。
10减4,得到6,将6放入队列中。
10减1,得到9,将9放入队列中。
第三轮遍历完毕。去掉重复元素,此时队列中还有1,3,4,6,9。

第四轮:
1减1,得到0。结束循环。直接返回此时层数。由于遍历了四轮,因此返回4。

代码如下:

 def numSquares(self, n):
        nums_to_subtract = []
        i = 1
        while i**2 <= n:
            nums_to_subtract.append(i**2)
            i += 1

        depth = 0
        current_level_nodes = {n}

        while True:
            nodes = current_level_nodes
            current_level_nodes = set()
            depth += 1
            for num_left in nodes:
                for num in nums_to_subtract:
                    if num_left < num:
                        break
                    elif num_left > num:
                        current_level_nodes.add(num_left - num)
                    else:
                        return depth
点赞
收藏
评论区
推荐文章
Stella981 Stella981
4年前
Ganglia的安装配置
监控节点需要安装的软件:GangliaGangliawebPhpApache被监控节点需要安装的软件Ganglia安装路径规划:软件名称路径ganglia安装路径/usr/local/gangliaphp安装路径/usr/loca
Wesley13 Wesley13
4年前
Java实现 LeetCode 814 二叉树剪枝 (遍历树)
814\.二叉树剪枝给定二叉树根结点root,此外树的每个结点的值要么是0,要么是1。返回移除了所有不包含1的子树的原二叉树。(节点X的子树为X本身,以及所有X的后代。)示例1:输入:\1,null,0,0,1\输出:\1,null,0,null,1\解释:
Wesley13 Wesley13
4年前
PHP数据结构与算法:二叉树
一、定义二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(leftsubtree)和“右子树”(rightsubtree)。二、特性1.在二叉树的第i层上至多有2^(i1)个结点(i0)2.深度为k的二叉树至多有2^k1个结点(k0)3.对于任意一棵二叉树,如果其叶结点数为N0,而
Stella981 Stella981
4年前
LeetCode(110):平衡二叉树
Easy!题目描述:给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树_每个节点_的左右两个子树的高度差的绝对值不超过1。示例1:给定二叉树 3,9,20,null,null,15,73/\920/
Wesley13 Wesley13
4年前
C语言递归之二叉树的最小深度
https://www.cnblogs.com/shichampion/p/12262678.html题目描述给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。说明: 叶子节点是指没有子节点的节点。示例输入:3,9,20,null,null,15,7
Stella981 Stella981
4年前
LeetCode112
非商业,LeetCode链接附上:https://leetcodecn.com/problems/pathsum/进入正题。题目:给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。说明: 叶子节点是指没有子节点的节点。示例:给定如下二叉树,以及目标和
贾蔷 贾蔷
8个月前
【蓝桥杯2015省赛解析】生命之树(洛谷P8625):树形DP解题全攻略
一、题目解读“生命之树”是一道经典的树形结构问题,要求计算一棵带权树中,以某个节点为根的最大子树权值和。题目输入为n个节点及边信息,每个节点有权值wi,需找到所有节点中,子树权值和最大的节点,并输出其值。核心挑战在于如何处理树形结构的递归关系,并高效聚合子
深度学习 深度学习
8个月前
【CSP-S 2019】括号树(洛谷P5658):栈+DFS
一、题目解读括号树问题(洛谷P5658)要求处理一个由括号序列转化的树结构:每个节点表示一个括号,'('为子节点,')'为父节点。题目给定一棵n个节点的树,需计算每个节点的深度(括号层数),并输出所有节点深度与节点编号乘积的异或和。核心在于将括号序列转化为
贾蔷 贾蔷
8个月前
牛客13279题解:利用递归与深度优先搜索计算树的最大高度(附完整代码)
一、题目解读牛客13279题要求计算给定树的最大高度。题目输入一棵以邻接表形式表示的树(节点从0开始编号),需要输出从根节点到最深叶节点的最长路径长度。树的结构由n个节点和n1条边构成,保证为连通无环图。理解题目核心在于准确获取树的拓扑关系,并设计算法遍历
贾蔷 贾蔷
9个月前
力扣145题:二叉树的后序遍历, 解题思路与C++实现
题目介绍力扣第145题要求实现一个函数,该函数接收一个二叉树的根节点,并返回该树的后序遍历结果。后序遍历是一种遍历二叉树的算法,其顺序为:先遍历左子树,是右子树,是根节点。解题思路分析解题时,我们可以使用递归或迭代的方法。递归方法较为直观,但可能导致栈溢出
贾蔷 贾蔷
8个月前
牛客12576题全解析:动态规划+质因数分解解决跳跃问题
一、题目解读牛客12576题是一道经典的算法题,要求给定起点N和终点M,求解从N到M的最少跳跃次数。题目考察的核心在于路径优化与动态规划思想,需结合数论中的质因数分解技巧,通过合理设计算法降低时间复杂度,避免暴力枚举的指数级耗时。二、解题思路采用“动态规划