前端算法必刷题系列[76] |8月更文挑战

512 阅读3分钟

这个系列没啥花头,就是纯 leetcode 题目拆解分析,不求用骚气的一行或者小众取巧解法,而是用清晰的代码和足够简单的思路帮你理清题意。让你在面试中再也不怕算法笔试。

今天来一些简单的二叉树问题,为后面二叉树更复杂情况做铺垫,二叉树一定要思考对称性,并利用递归做左右分治

142. 合并二叉树 (merge-two-binary-trees)

标签

  • 二叉树
  • 简单

题目

leetcode 传送门

这里不贴题了,leetcode打开就行,题目大意:

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。

你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

示例 1

输入: 
	Tree 1                     Tree 2                  
          1                         2                             
         / \                       / \                            
        3   2                     1   3                        
       /                           \   \                      
      5                             4   7                  
输出: 
合并后的树:
	     3
	    / \
	   4   5
	  / \   \ 
	 5   4   7

基本思路

简单问题,其实重点就是递归去合并左右子树,先根节点的合并

合并就是3种情况

  • 有一边为空,直接返回另一棵树
  • 两边需要相加
  • 都是空,直接返回 null

那么下面来看下写法,看代码注释完全没问题

写法实现

var mergeTrees = function(root1, root2) {
  // 如果有一棵树是空的直接返回另一棵树就行
  if (root1 === null) {
    return root2
  }
  if (root2 === null) {
    return root1
  }
  // 把两个树的根节点值相加在第一个树
  root1.val += root2.val
  // 递归去做左右子树的合并
  root1.left = mergeTrees(root1.left, root2.left)
  root1.right = mergeTrees(root1.right, root2.right)
  // 最后返回第一个树
  return root1
};

143. 翻转二叉树 (invert-binary-tree)

标签

  • 二叉树
  • 简单

题目

leetcode 传送门

这里不贴题了,leetcode打开就行,题目大意:

翻转一棵二叉树。

示例 1

输入

     4
   /   \
  2     7
 / \   / \
1   3 6   9

输出

     4
   /   \
  7     2
 / \   / \
9   6 3   1

基本思路

这个问题还有个有趣的故事,Max Howell (Homebrew作者) 在 google 面试失败时收到的回信:

谷歌:我们90%的工程师使用您编写的软件(Homebrew),但是您却无法在面试时在白板上写出翻转二叉树这道题,这太糟糕了。

其实还是一个对对称性的问题,左右子树分别递归翻转。

二叉树的问题,你需要思考的是一边如何做,因为另一边其实一模一样,因为是对称的。

递归底层是叶子,进行翻转,然后一级级往上,最后到根的左右子树翻转就全部翻转了。

同样反过来想,从根开始先交换左右儿子,再一层层往下,最后交换叶子也是可以的,不要局限思路。

写法实现

从叶到根

var invertTree = function(root) {
  if (root === null) {
    return null
  }
  // 递归去获取已经翻过来的左右子树
  let leftReverse = invertTree(root.left)
  let rightReverse = invertTree(root.right)
  // 再把根的左右交换
  root.left = rightReverse
  root.right = leftReverse
  // 返回根
  return root
};

从根到叶

var invertTree = function(root) {
  if (root === null) {
    return null
  }
  // 先交换当前根的左右
  [root.left, root.right] = [root.right, root.left]
  // 再递归去搞左右子树
  invertTree(root.left)
  invertTree(root.right)
  // 返回根
  return root
};

另外向大家着重推荐下这个系列的文章,非常深入浅出,对前端进阶的同学非常有作用,墙裂推荐!!!核心概念和算法拆解系列

今天就到这儿,想跟我一起刷题的小伙伴可以加我微信哦 点击此处交个朋友 Or 搜索我的微信号infinity_9368,可以聊天说地 加我暗号 "天王盖地虎" 下一句的英文,验证消息请发给我 presious tower shock the rever monster,我看到就通过,加了之后我会尽我所能帮你,但是注意提问方式,建议先看这篇文章:提问的智慧

参考