669. 修剪二叉搜索树
卡哥建议:这道题目比较难,比 添加增加和删除节点难的多,建议先看视频理解。
题目链接/文章讲解:https://programmercarl.com/0669.%E4%BF%AE%E5%89%AA%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91.html
视频讲解:https://www.bilibili.com/video/BV17P41177ud做题思路:
递归处理,区间 [low, high],遇到 root->val < low || root->val > high
的时候直接return NULL,
还有一种情况考虑不符合区间的节点,它的左子树或者右子树有符合区间的节点,比如,那么将节点0的右孩子 节点2 直接赋给 节点3的左孩子就可以了(就是把节点0从二叉树中移除),如图:
本题代码:
1 class Solution { 2 public: 3 TreeNode* trimBST(TreeNode* root, int low, int high) { 4 if (root == nullptr ) return nullptr; 5 if (root->val < low) { //从根节点开始遍历,如果根节点小于区间左边界值,说明根节点是要修剪的节点,根据搜索树的特点,从根节点的右子树开始寻找符合区间的 6 TreeNode* right = trimBST(root->right, low, high); // 寻找符合区间[low, high]的节点 7 return right; 8 } 9 if (root->val > high) { 10 TreeNode* left = trimBST(root->left, low, high); // 寻找符合区间[low, high]的节点 11 return left; 12 } 13 root->left = trimBST(root->left, low, high); // root->left接入符合条件的左孩子 14 root->right = trimBST(root->right, low, high); // root->right接入符合条件的右孩子 15 return root; 16 } 17 };
108.将有序数组转换为二叉搜索树
卡哥建议:本题就简单一些,可以尝试先自己做做。
https://programmercarl.com/0108.%E5%B0%86%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E8%BD%AC%E6%8D%A2%E4%B8%BA%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91.html
视频讲解:https://www.bilibili.com/video/BV1uR4y1X7qL做题思路:
根据有序数组构造一棵二叉树。本质就是寻找分割点,分割点作为当前节点,然后递归左区间和右区间。分割点就是数组中间位置的节点。
如果数组长度为偶数,中间节点有两个,取哪一个都可以,只不过构成了不同的平衡二叉搜索树。
比如,如果要分割的数组长度为偶数的时候,中间元素为两个,是取左边元素 就是树1,取右边元素就是树2。
本题代码:
1 class Solution { 2 private: 3 TreeNode* traversal(vector<int>& nums, int left, int right) { 4 if (left > right) return nullptr; //非法区间 5 int mid = left + ((right - left) / 2); //切割点 6 TreeNode* root = new TreeNode(nums[mid]); 7 root->left = traversal(nums, left, mid - 1); //区间为左闭右闭,所以 mid-1 为对应下标的值,这里看卡哥视频理解 8 root->right = traversal(nums, mid + 1, right); 9 return root; 10 } 11 public: 12 TreeNode* sortedArrayToBST(vector<int>& nums) { 13 TreeNode* root = traversal(nums, 0, nums.size() - 1); 14 return root; 15 } 16 };
538.把二叉搜索树转换为累加树
卡哥建议:本题也不难,在 求二叉搜索树的最小绝对差 和 众数 那两道题目 都讲过了 双指针法,思路是一样的。
https://programmercarl.com/0538.%E6%8A%8A%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E8%BD%AC%E6%8D%A2%E4%B8%BA%E7%B4%AF%E5%8A%A0%E6%A0%91.html
视频讲解:https://www.bilibili.com/video/BV1d44y1f7wP
做题思路:
二叉搜索树的有序数组,是按中序遍历得到的,就是左中右,那累加的话,理解题意后,就是从后到前加起来,顺序是右中左。
所以我们需要反中序遍历这个二叉树,然后顺序累加就可以了。
本题依然需要一个pre指针记录当前遍历节点cur的前一个节点,这样才方便做累加。
本题代码:
1 class Solution { 2 private: 3 int pre = 0; // 记录前一个节点的数值 4 void traversal(TreeNode* cur) { // 右中左遍历 5 if (cur == NULL) return; 6 traversal(cur->right); //右 7 cur->val += pre;//中 8 pre = cur->val; 9 traversal(cur->left);//左 10 } 11 public: 12 TreeNode* convertBST(TreeNode* root) { 13 pre = 0; 14 traversal(root); 15 return root; 16 } 17 };
总结:
https://programmercarl.com/%E4%BA%8C%E5%8F%89%E6%A0%91%E6%80%BB%E7%BB%93%E7%AF%87.html
标签:right,TreeNode,随想录,E6%,二叉,搜索,root,节点,left From: https://www.cnblogs.com/romantichuaner/p/17646804.html