- 你只需要思考每一个节点应该做什么,其他的不用你管,抛给二叉树遍历框架,递归会对所有节点做相同的操作。
- 遇到一道二叉树的题目时的通用思考过程是:是否可以通过遍历一遍二叉树得到答案?如果不能的话,是否可以定义一个递归函数,通过子问题(子树)的答案推导出原问题的答案? 如果需要用到子树信息, 一般使用后序遍历.
二叉树题目的递归(DFS)解法可以分两类思路:
- 第一类是遍历一遍二叉树得出答案:对应着 回溯算法核心框架
- 第二类是通过分解问题计算出答案:对应着 动态规划核心框架。
以求二叉树最大深度为例:
- 解法一:遍历一遍二叉树
- 解法二:分解问题。定义一个递归函数,通过子问题(子树)的答案推导出原问题的答案
二叉树的解题思路就可以归类为上述两种思路:
- 是否可以通过遍历一遍二叉树得到答案?
- 如果不能的话,是否可以定义一个递归函数,通过子问题(子树)的答案推导出原问题的答案?
构建二叉树
根据层序遍历序列 {1, 2, 3, -1, -1, 4, 5} 构建二叉树:-1 代表 nullptr
#include <iostream>#include <vector>#include <queue>using namespace std;struct TreeNode {int val;TreeNode* left;TreeNode* right;TreeNode() : val(0), left(nullptr), right(nullptr) {}TreeNode(int num) : val(num), left(nullptr), right(nullptr) {}};int main(){vector<int> nodeList = {1, 2, 3, -1, -1, 4, 5}; // -1 代表 nullptrTreeNode* root = new TreeNode(nodeList[0]);queue<TreeNode*> nodeQ;nodeQ.push(root);int idx = 1;while(!nodeQ.empty() && idx < nodeList.size()){TreeNode* cur = nodeQ.front();nodeQ.pop();if(nodeList[idx] != -1){cur->left = new TreeNode(nodeList[idx]);nodeQ.push(cur->left);}if(idx + 1 < nodeList.size() && nodeList[idx + 1] != -1){cur->right = new TreeNode(nodeList[idx + 1]);nodeQ.push(cur->right);}idx += 2;}while(!nodeQ.empty())nodeQ.pop();nodeQ.push(root);while(!nodeQ.empty()){int levelSize = nodeQ.size();for(int i = 0; i < levelSize; ++i){TreeNode* cur = nodeQ.front();nodeQ.pop();cout << cur->val << " ";if(cur->left != nullptr)nodeQ.push(cur->left);if(cur->right != nullptr)nodeQ.push(cur->right);}cout << endl;}return 0;}
