538. 把二叉搜索树转换为累加树
给定一个二叉搜索树(Binary Search Tree),把它转换成为累加树(Greater Tree),使得每个节点的值是原来的节点值加上所有大于它的节点值之和。
例如:
输入: 原始二叉搜索树:
5
/
2 13
输出: 转换为累加树:
18
/
20 13
二叉搜索树:
1.如果root有左孩子,那么他的左孩子都比都比他小
2.如果root有右孩子,那么他的右孩子都比都比他大
3.root的孩子也具有以上性质
二叉搜索树的性质告诉我们:中序遍历得到的数组是有序的
解法一:
反向中序遍历:
先来看普通的中序遍历
if(root){
traversal(root->left);
//visit val and do some operation;
cout << root->val;
tracersal(root->right);
}
那么反向中序遍历就将顺序倒过来
if(root){
traversal(root->right);
//visit val and do some operation;
cout << root->val;
tracersal(root->left);
}
代码:
class Solution
{
public:
int sum = 0;
TreeNode *convertBST(TreeNode *root)
{
if(root){
convertBST(root->right);
sum += root->val;
root->val = sum;
convertBST(root->left);
}
MorisTraversal(root);
return root;
}
};
解法二:
Morris Traversal
算法描述:
一:cur有左孩子,找到左孩子的最右节点 记作mostRgight
Ⅰ:如果mostRgight->right == NULL,则mostRgight->right = cur, cur=cur->left;
Ⅱ:如果mostRgight->right != NULL,则mostRgight->rihgt = null,cur=cur->right;
二:如果cur无左孩子,访问该节点,cur=cur->rightl;
这实际上是一个搭桥和拆桥的过程,在纸上画出路径和mostright的指向就可以直观的看出来
比如 就{2,1,3}这棵二叉搜索树举例,cur==root时,mostright会指向1所在的节点,然后搭桥,mostRgight->right = cur,然后cur向左遍历cur=cur-left,cur遍历至1所在节点的时候,拆桥mostRgight->rihgt = null,然后向右边遍历cur=cur->right;
如果cur没有左孩子,那么cur过桥,cur = cur->right;
while(root){
if(root->left != NULL){
TreeNode* temp = root->left;
//找到mostright
while(temp->right != NULL && temp->right != root) temp = temp->right;
//因为这里有两个限制条件,因此需要分类讨论
if(temp->right == NULL){
//搭桥
temp->right = root;
root = root->left;
}
else{
//拆桥
temp->right = NULL;
root = root->right;
}
}
else{
//过桥
root = root->right;
}
}
回到这题,我们需要反向中序遍历,那么把left和right交换一下就好了
代码:
class Solution
{
public:
int sum = 0;
void MorisTraversal(TreeNode *root)
{
while (root)
{
if (root->right != NULL)
{
TreeNode *temp = root->right;
//temp:右子树最左节点
while (temp->left != NULL && temp->left != root)
{
temp = temp->left;
}
//two situation
if (temp->left == NULL)
{
//first visit
temp->left = root; //construct the bridge
root = root->right;
}
else
{
//at the monment temp->right = root
//second visit and do some operation
//deconstruct the bridge
temp->left = NULL;
cout << root->val << " ";
sum += root->val;
root->val = sum;
root = root->left;
}
}
else
{
//visit val;
cout << root->val << " ";
sum += root->val;
root->val = sum;
root = root->left;
}
}
}
TreeNode *convertBST(TreeNode *root)
{
// if(root){
// convertBST(root->right);
// sum += root->val;
// root->val = sum;
// convertBST(root->left);
// }
MorisTraversal(root);
return root;
}
};