一、543. 二叉树的直径
LeetCode:543. 二叉树的直径
二叉树的直径 = 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。
遇到二叉树的问题很容易去直接用求解的目标去定义递归函数。但是仔细考虑,返回树的直径并不能向上传播。因此我们可以拆分成两步:
- 树的直径 = 左儿子的高度 + 右儿子的高度 + 2
因此我们只需要求高度就行。
树求高度实际上是一个树形dp
:dp[root] = max(dp[child]) +1
class Solution {
public:int diameterOfBinaryTree(TreeNode* root) {max_len = 0;height(root);return max_len;}
private:int height(TreeNode * root){if(!root) return -1;//没有结点时,高度为-1。有一个结点时,高度为0int left_height = height(root->left);//左儿子高度int right_height = height(root->right);//右儿子高度max_len = max(max_len, left_height + right_height + 2);return max(left_height, right_height) + 1;//返回以root为根的子树的高度。}int max_len;
};
二、108. 将有序数组转换为二叉搜索树
LeetCode:108. 将有序数组转换为二叉搜索树
二叉搜索树(二叉查找树) : 对于任意节点,其左子树的所有节点的值小于该节点的值,其右子树的所有节点的值大于等于该节点的值。
这里需要注意的是,题目所给的nums 按 严格递增 顺序排列
。因此,我们可以根据平衡二叉查找树的性质(左右子树高度差不大于1),通过下标直接找到根结点的位置(中间位置的结点)。
- 当总结点个数为奇数时,中间位置的结点左右两边的结点个数相同,很显然左右子树结点个数相同,采用相同形状则高度是相同的。
- 当总结点个数为偶数时,中间位置的结点右边的结点个数 比 左边结点个数多1。对于本中间位置结点而言,由于左右子树的生成规则相同,右子树的高度最多比左子树的高度多1。
- 程序递归执行,因此所有结点皆满足这样的性质,则可以构建一颗平衡二叉树。
类似于:构建完全二叉查找树
class Solution {
public:TreeNode* sortedArrayToBST(vector<int>& nums) {return createTree(nums, 0, nums.size()-1);}
private:TreeNode * createTree(vector<int> & nums, int L, int R){if(L > R) return nullptr;int mid = (L + R) >> 1;TreeNode * root = new TreeNode(nums[mid], createTree(nums, L, mid - 1), createTree(nums, mid + 1, R));return root;}
};