📢前言
🚀 算法题 🚀
🌲 每天打卡一道算法题,既是一个学习过程,又是一个分享的过程😜
🌲 提示:本专栏解题 编程语言一律使用 C# 和 Java 两种进行解题
🌲 要保持一个每天都在学习的状态,让我们一起努力成为算法大神吧🧐!
🌲 今天是力扣算法题持续打卡第32天🎈!
🚀 算法题 🚀
🌲原题样例:路径总和
给你二叉树的根节点root和一个表示目标和的整数 targetSum,判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和targetSum 。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22 输出:true
示例 2:
输入:root = [1,2,3], targetSum = 5 输出:false
示例 3: 输入:root = [1,2], targetSum = 0 输出:false
提示:
树中节点的数目在范围 [0, 5000] 内
-1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000
🌻C#方法:递归
观察要求我们完成的函数,我们可以归纳出它的功能:询问是否存在从当前节点root到叶子节点的路径,满足其路径和为 sum。
假定从根节点到当前节点的值之和为 val,我们可以将这个大问题转化为一个小问题:是否存在从当前节点的子节点到叶子的路径,满足其路径和为 sum - val。
不难发现这满足递归的性质,若当前节点就是叶子节点,那么我们直接判断 sum 是否等于 val 即可(因为路径和已经确定,就是当前节点的值,我们只需要判断该路径和是否满足条件)。若当前节点不是叶子节点,我们只需要递归地询问它的子节点是否能满足条件即可。
思路解析
代码:
public class Solution { public bool HasPathSum(TreeNode root, int sum) { //出口 if (root == null) { return false; } if (root.left == null && root.right == null) { return root.val == sum; } return HasPathSum(root.left, sum - root.val) || HasPathSum(root.right, sum - root.val); } }
执行结果
通过 时间复杂度:O(n),其中 N 是树的节点数。 空间复杂度:O(H),其中 H 是树的高度
复杂度分析
时间复杂度:O( n^2 ),其中 n 是数组的长度。每个数字只访问一次。 空间复杂度:O( n ),其中 n 是数组的长度。空间复杂度不考虑返回值,因此空间复杂度主要取决于递归栈的深度,递归栈的深度是O(logn)
🌻Java 方法一:广度优先搜索
思路解析
首先我们可以想到使用广度优先搜索的方式,记录从根节点到当前节点的路径和,以防止重复计算。
这样我们使用两个队列,分别存储将要遍历的节点,以及根节点到这些节点的路径和即可。
代码:
class Solution { public boolean hasPathSum(TreeNode root, int sum) { if (root == null) { return false; } Queue<TreeNode> queNode = new LinkedList<TreeNode>(); Queue<Integer> queVal = new LinkedList<Integer>(); queNode.offer(root); queVal.offer(root.val); while (!queNode.isEmpty()) { TreeNode now = queNode.poll(); int temp = queVal.poll(); if (now.left == null && now.right == null) { if (temp == sum) { return true; } continue; } if (now.left != null) { queNode.offer(now.left); queVal.offer(now.left.val + temp); } if (now.right != null) { queNode.offer(now.right); queVal.offer(now.right.val + temp); } } return false; } }
执行结果
通过 执行用时:2 ms,在所有 Java 提交中击败了10.29%的用户 内存消耗:38.3 MB,在所有 Java 提交中击败了67.32%的用户
复杂度分析
时间复杂度:O( n ),其中 N 是树的节点数。 空间复杂度:O( n ),其中 N 是树的节点数。
🌻Java 方法二:递归
思路解析
观察要求我们完成的函数,我们可以归纳出它的功能:询问是否存在从当前节点root到叶子节点的路径,满足其路径和为 sum。
假定从根节点到当前节点的值之和为 val,我们可以将这个大问题转化为一个小问题:是否存在从当前节点的子节点到叶子的路径,满足其路径和为 sum - val。
不难发现这满足递归的性质,若当前节点就是叶子节点,那么我们直接判断 sum 是否等于 val 即可(因为路径和已经确定,就是当前节点的值,我们只需要判断该路径和是否满足条件)。若当前节点不是叶子节点,我们只需要递归地询问它的子节点是否能满足条件即可。
代码:
class Solution { public void merge(int[] nums1, int m, int[] nums2, int n) { int p1 = 0, p2 = 0; int[] sorted = new int[m + n]; int cur; while (p1 < m || p2 < n) { if (p1 == m) { cur = nums2[p2++]; } else if (p2 == n) { cur = nums1[p1++]; } else if (nums1[p1] < nums2[p2]) { cur = nums1[p1++]; } else { cur = nums2[p2++]; } sorted[p1 + p2 - 1] = cur; } for (int i = 0; i != m + n; ++i) { nums1[i] = sorted[i]; } } }
执行结果
通过 执行用时:0 ms,在所有 Java 提交中击败了100.00%的用户 内存消耗:38.5 MB,在所有 Java 提交中击败了18.28%的用户
复杂度分析
时间复杂度:O(n),其中 N 是树的节点数。 空间复杂度:O(H),其中 H 是树的高度
💬总结
- 今天是力扣算法题打卡的第三十二天!
- 文章采用
C#
和Java
两种编程语言进行解题 - 一些方法也是参考力扣大神写的,也是边学习边分享,再次感谢算法大佬们