代码随想录算法训练营第十六天[二刷] | 找寻二叉的深度

104.二叉树的最大深度

递归

首先知道 题目问的整个树的最大的深度 = root 的高度 这样用post-order 写起来会很方便

为什么Post - order? 处理完子树之后,再 把数值(本题中是高度) 传递给他们的父结点,一层层想上传递信息

相反,pre-order 是先处理好上层逻辑再把需要的数据向下传递.

文字表述过程:

  1. 先找左边,
  2. 再找右边,(
    (左右顺序不重要,只要找到之后返回上去即可)
  3. 最后拿到了左右子树高度的信息,取到最大值 + 1(本层逻辑)

111.二叉树的最小深度

递归

首先,这道题也可以用后序遍历解决。
但是有一个问题,当我们取最小值的时候,一旦有空子树(即depth =0 )因为取最小值, 它就会被选中
而题目的要求是不考虑无子树的条件/距离最近的子节点
所以直接的解法就是在取height值的时候,把这种特殊情况考虑进来去掉

如何在代码里体现?
首先是general 的情况: 左右都有node: 逻辑就和最大深度十分相似: minDepth(left ,right) +1
corner case就是: 左子树为空[左右枝丫都没有], 右不为空: 为空的话,就不需要考虑这边的节点,直接返回另一边的height即可

222.完全二叉树的节点个数

  • 基本版本

思路非常的简单,遍历,并且无论何种遍历都可以解决。
而在每次遍历的基础上,把数到的这个点算进去(自己 + 1)。
自己没想到,还蠢蠢的跑去数单次递归下的结点的左右子树。其实直接把当前 +1 就完成了count…
二刷的我,果不其然 又又又去数点了,我用了递归遍历中最古老繁琐的方法: 定义全局变量res, 利用一个递归(辅助)函数(返回void 因为是对全局变量进行操作)去数点,最后把res 返回即可。

  • 升级版本

因为他给定了该tree一定是完全二叉树, 那也就是说子节点从左到右一定是连续的 ,这是前提。
之后比较巧妙:如果我们可以判断出来是满二叉树的话,直接用公式计算即可。那如何判断是满二叉树呢?只要一直往左边和右边循环走到头,算出来的Height 是相等的。那中间肯定是满的(运用了完全二叉树的特性) 直接返回 2^n - 1即可,如果不相等,那就正常递归,最后肯定会有一个满2叉数否则为Null 直接就返回0了, 这样也不会一直在循环里不出来。

代码的实现着实又为难了我一把,先理解递归+ 循环的写法:
1,root为空的话,直接返回0。2, 进入到每一层先进行循环的计算看左边和最右边的height是否一样? 一样就可以返回 (1 << left ) 不一样的话就乖乖的进行常规遍历

if(leftH = rightH)
return (int) Math.pow(2, leftH) - 1;
else
return count(root.left) + count( root.right) + 1
  • 升级v2,更巧妙的方法:
  1. 数count的时候,根据 完全二叉树的性质:其实只要一直向左走,就可以获得最大深度。
  2. 得到的height 有2种情况,高度相等 OR 不相等。[记住,处理单层递归,我得到的是上一层给我的返回值,也就是说是上一层的depth]
    - 相等: 左边上层节点和[ 2^ld -1]+当前左根节点[1]+右总结点[Count(root.right)] 。
    - 不相等:(右边的上层节点一定是个满2叉)右边上层节点和 [2^rd - 1] + 左边的当前根节点[1] +左总节点[Count(root.left)]

Ps: 通过这几道题,记一下自己对于递归的理解,还是有点迷茫,如果之后继续刷树会有更深的理解在跑过来更新。 从 root 开始向下进发,所以会有root.left Or root.right 这些下一个阶段需要用的值作为参数放到递归函数里。
但是一个个回退(return)的时候, 以数的理解是从下往上回收数据。所以拿到的都是上一层的数据结果。
所以就像是,送进去的是 i +1 拿回来的也是他的返回,拿到之后我再做自己的逻辑运算

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第二十二算法训练营主要涵盖了Leetcode题目中的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28题,题目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组中找到长度最小的子数组,使得子数组的和大于等于给定的目标值。这里可以使用滑动窗口的方法来解决问题。使用两个指针来表示滑动窗口的左边界和右边界,通过移动指针来调整滑动窗口的大小,使得滑动窗口中的元素的和满足题目要求。具体实现的代码如下: ```python def minSubArrayLen(self, target: int, nums: List[int]) -> int: left = 0 right = 0 ans = float('inf') total = 0 while right < len(nums): total += nums[right] while total >= target: ans = min(ans, right - left + 1) total -= nums[left] left += 1 right += 1 return ans if ans != float('inf') else 0 ``` 以上就是第二十二算法训练营的内容。通过这些题目的练习,可以提升对双指针和滑动窗口等算法的理解和应用能力。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值