Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus sum of all keys greater than the original key in BST.
Input: The root of a Binary Search Tree like this: 5 / \ 2 13 Output: The root of a Greater Tree like this: 18 / \ 20 13
/**
*Definition for a binary tree node.
*struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(intx) : val(x), left(NULL), right(NULL) {}
* };
*/
方法一:我的笨拙的方法
class Solution {
public:
TreeNode* convertBST(TreeNode* root) {
if(root==NULL)
{
return NULL;
}
int sum=sumBST(root);
stack<TreeNode*>s;
TreeNode* pcurr=root;
while(!s.empty()||pcurr!=NULL)
{
while(pcurr!=NULL)
{
s.push(pcurr);
pcurr=pcurr->left;
}
if(!s.empty())
{
pcurr=s.top();
s.pop();
sum=sum-(pcurr->val);
pcurr->val+=sum;//+=,别把符号写错了。要不然很费劲的
pcurr=pcurr->right;
}
}
return root;
}
int sumBST(TreeNode* root)//先求出所有节点之和
{
if(root==NULL)
{
return 0;
}
return sumBST(root->left)+sumBST(root->right)+root->val;
}
};
方法二:递归版本
中序遍历,采用先遍历右子树的方法,在遍历左子树。真他妈的巧妙,我的思维还一直停在固有思维上(先遍历左子树后遍历右子树),其实可以想象,当采用中序遍历时,若采用先遍历右子树后遍历左子树,则得到的序列是从大到小的序列。很方便计算出比当前节点大的节点值之和。
class Solution {
public:
TreeNode* convertBST(TreeNode* root) {
int sum=0;
conver(root,sum);
return root;
}
void conver(TreeNode* root,int &sum)
{
if(root==NULL)
{
return;
}
conver(root->right,sum);
root->val+=sum;
sum=root->val;
conver(root->left,sum);
}
};
方法三:优化版本:非递归
对root所指二叉树的节点指向有效。
class Solution {
public:
TreeNode* convertBST(TreeNode* root) {
if(root==NULL)
{
return NULL;
}
int sum=0;
stack<TreeNode*>s;
TreeNode* pcurr=root;
while(!s.empty()||pcurr!=NULL)
{
while(pcurr!=NULL)
{
s.push(pcurr);
pcurr=pcurr->right;//先处理右子树,后处理左子树
}
if(!s.empty())
{
pcurr=s.top();
s.pop();
pcurr->val+=sum;//+=,别把符号写错了。要不然很费劲的
sum=pcurr->val;
pcurr=pcurr->left;
}
}
return root;
}
};
结果:对中序遍历,理解更深了。