Tree and Divide Conquer
最近做二叉树相关的题,被递归搞的晕头转向。
[TOC]
一、树的性质
参考:Tree总结
由于树的结构,这种数据结构很适合用分治(Divide Conquer)
Divide and Conquer模版
递归算法模版;
1 | def traversal(root): |
114 Flatten Binary Tree to Linked List
以 leetcode #114题为例
1)从最简单的case开始
simplest case,树只有一个元素1,直接返回;
1 | # simplest case: |
当有两个元素时:
1 | def flatten2(root): |
当有三个元素时:
1 | def flatten3(root): |
2)一般case
可以将其分为 左子树和右子树,(假设左右都为三个元素(base case),我们可以用上面的程序处理好)。假设左右子树都已经处理完毕。
1 | def flatten(root): |
3) merge
如何把子问题的解merge原问题的解?
把子问题的解 merge成问题的解时需要解决一个问题,即如何将右子树链接到左子树的后面?
- 左子树的哪个节点去链接右子树根节点?
- 如何确定这个节点的位置
根据题意知道,最终生成 linked list 顺序是先序遍历的顺序,故将左子树最右边的叶子节点链接到右子树的根节点;使用python中的全局变量指向当前根节点下的最右叶子节点。
算法:
1 | prev = None |
最终AC的代码:
Python3代码:
1 | # Definition for a binary tree node. |
代码精简版:
1 | # Definition for a binary tree node. |
从以上代码可以看出,其实就是对 Tree 进行先序遍历
,同时将全局变量用作指针
这道题还有其他思路,(修改版的后序遍历)遍历顺序是右子树->左子树->根节点。
1 | # Definition for a binary tree node. |
总结
- 对树进行divide conquer ,要把所有的最简单case列出来分析
- 将树分为子问题一般比较容易,关键如何将子问题的解merge成原问题的解!
- python的全局变量的使用。