LC-617.合并二叉树

LC-617.合并二叉树

递归(先序遍历)

变量三步走:

  1. 确定递归函数的参数和返回值:

    要合并两个二叉树,所以参数至少传入两个二叉树的根节点,然后返回值就是合并后二叉树的根节点。

  2. 确定终止条件:

    这里我先给出一个便于理解的版本

    • 如果两个根节点都不存在,那么 return None
    • 如果 root1 不存在,那么直接返回 root2。这里和链表差不多,一个短的链表被遍历完了,长的链表直接接上就行了,不需要再遍历了,
    • 同上,如果 root2 不存在,那么直接返回 root1
    if not root1 and not root2:
        return None
    elif not root1:
        return root2
    elif not root2:
        return root1
    
  3. 确定单层递归逻辑:

    如果上面的情况都排除后,那么就一定是两个节点都存在。这时我采用的是新建一个空节点的方法,后面会介绍直接修改两个树中的一个树,这样更节约时间和空间。

    • 首选创建一个空节点 root
    • 同时递归两个根节点的左孩子,然后返回值作为 root 的左孩子;
    • 同时递归两个根节点的左孩子,然后返回值作为 root 的左孩子;

代码如下:

class Solution:
    def traverse(self, root1, root2):
        # 先序遍历
        if not root1 and not root2:
            return None
        elif not root1:
            return root2
        elif not root2:
            return root1
        else:
            root = TreeNode(root1.val + root2.val)
            root.left = self.traverse(root1.left, root2.left)
            root.right = self.traverse(root1.right, root2.right)
        return root

    def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
        return self.traverse(root1, root2)

代码优化

  • 优化1: 优化递归终止条件,但凡有一个节点为空, 就立刻返回另外一个。如果另外一个也为None也没关系,我们就直接返回None。这样优化以后,就不需要上面那样繁琐的判断过程了。
if not root1: return root2
if not root2: return root1
  • 优化2: 经过上面的判断后,root1root2 一定都是非空的。这时候,我们直接修改本来的两课二叉树之一,这里直接改变 root1 的树结构,而不是创建新的节点,这样节省时间和空间。
root1.val += root2.val # 中
root1.left = self.mergeTrees(root1.left, root2.left) #左
root1.right = self.mergeTrees(root1.right, root2.right) # 右

运行结果:

确实快了很多。

LC-617.合并二叉树_第1张图片

你可能感兴趣的:(leetcode,python,二叉树,递归)