LeetCode 669 修剪二叉搜索树
题目链接:https://leetcode.cn/problems/trim-a-binary-search-tree/
思路:
如果当前父节点值小于最小边界,那么其左子树可以直接完全修剪掉,右子树有可能存在符合条件的值,所以要继续往右遍历;同理,如果当前父节点值大于最大边界,那么其右子树可以直接完全修剪掉,左子树有可能存在符合条件的值,所以要继续往左遍历
代码:
递归法
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* trimBST(TreeNode* root, int low, int high) {
if(!root) return nullptr;
if(root->val<low)
{
// 因为其右子树可能会满足条件,也有可能右子树部分满足条件,所以需要将右子树整个遍历一遍
TreeNode *right = trimBST(root->right,low,high);
return right;
}
if(root->val>high)
{
TreeNode *left = trimBST(root->left,low,high);
return left;
}
root->left = trimBST(root->left,low,high);
root->right = trimBST(root->right,low,high);
return root;
}
};
总结
修剪的思路是想到了的,只不过写的时候写的和昨天删除节点的值相类似,没有想明白遇到了父节点值该如何一直向左或向右遍历,将整棵树遍历完。
LeetCode 108 将有序数组转换为二叉搜索树
题目链接:https://leetcode.cn/problems/convert-sorted-array-to-binary-search-tree/
思路:
类似用后序与中序构建二叉树,不过比那道题还要简单。因为是有序数组,所以节点元素必然是中间位置的值,然后再左右划分数组即可。注:如果数组大小为偶数,那么中间值会有两个,这样就会出现两种情况,这也是题目中说答案不唯一的原因。
代码:
创建新数组法
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
// 1、终止条件
if(nums.empty())
return nullptr;
// 2、寻找节点元素
int index = nums.size()/2;
int rootval = nums[index];
TreeNode *root = new TreeNode(rootval);
// 处理叶子节点
if(nums.size()==1)
return root;
// 3、切割有序数组
vector<int>left(nums.begin(),nums.begin()+index);
vector<int>right(nums.begin()+index+1,nums.end());
// 4、递归处理左右子树
root->left = sortedArrayToBST(left);
root->right = sortedArrayToBST(right);
return root;
}
};
下标法
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
TreeNode *root = traversal(nums,0,nums.size());
return root;
}
TreeNode* traversal(vector<int>& nums,int left,int right)
{
if(left>=right) return nullptr;
int mid = left+((right-1-left)/2); // 避免越界
TreeNode *root = new TreeNode(nums[mid]);
root->left = traversal(nums,left,mid);
root->right = traversal(nums,mid+1,right);
return root;
}
};
总结
比昨天的中序与后序构造二叉树简单,可以自己完整写出来
LeetCode 538 把二叉搜索树转换为累加树
题目链接:https://leetcode.cn/problems/convert-bst-to-greater-tree/
思路:
累加的意思是:倒序将二叉树的各节点值累加起来
从最右边节点8开始,然后到上一个节点7,要累加8,所以变成了15,然后到节点6......,依次类推。
遍历方式:
代码:
双指针法-自写
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode *pre = nullptr;
TreeNode* convertBST(TreeNode* root) {
if(!root) return nullptr;
root->right = convertBST(root->right);
if(pre)
{
root->val += pre->val;
}
pre = root;
root->left = convertBST(root->left);
return root;
}
};
卡哥代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int pre = 0; // 记录前一个节点的值
TreeNode* convertBST(TreeNode* root) {
traversal(root);
return root;
}
void traversal(TreeNode *cur)
{
if(!cur) return ;
traversal(cur->right);
cur->val += pre;
pre = cur->val;
traversal(cur->left);
}
};
总结
一开始没理解题目什么意思,看了视频前半段讲解才理解题目意思,然后很轻松的就写出来了代码。
今日总结:
二叉树到此终于完结了,二叉树章节题目很多,有很多题目很难,没接触过,现在回想起来再重新写,估计也很难写出来,在后面做题的时候要一边做一边复习一下之前写过的题目。一刷肯定不够的,二刷搞起,希望有时间可以三刷。