题目:https://leetcode-cn.com/problems/convert-bst-to-greater-tree/submissions/
思路一:递归
- 分析:由题意可知: 每个节点 node 的新值等于原树中大于或等于 node.val 的值之和;二叉搜索树的特性是右子树大于根节点大于左子树又因为每个节点的新值大于原树中大于或等于当前节点值的和,所以先遍历右子树,在处理 根节点,左后遍历左子树
步骤:
1. 写递归函数(右中左)
-
函数参数和返回值
传入树的根节点,因为节点的值为大于等于当前节点值的和,所以传入一个引用变量,用于保存处理过的节点的和(处理过的节点都比当前节点大);所以函数参数为根节点和引用变量,无返回值
-
终止的条件
节点为空就返回 -
.单层逻辑
递归右子树
如果当前节点不为空,引用变量加上当前节点的值的和作为当前节点的值
递归右子树
-
在目标函数定义一个变量,赋值为0,调用递归函数
-
返回根节点
class Solution {
private:
void travesal(TreeNode*cur,int &sum)
{
if(cur==NULL)
return;
travesal(cur->right,sum);
if(cur!=NULL)
{
sum+=cur->val;
cur->val=sum;
}
travesal(cur->left,sum);
}
public:
TreeNode* convertBST(TreeNode* root) {
int sum=0;
travesal(root,sum);
return root;
}
};
简化写法:
public:
int sum=0;
TreeNode* convertBST(TreeNode* root) {
if(root!=NULL)
{
convertBST(root->right);
sum+=root->val;
root->val=sum;
convertBST(root->left);
}
return root;
};
思路二:迭代法
思路和反序的中序遍历相同
TreeNode* convertBST(TreeNode* root) {
stack<TreeNode*>stk;
if(root==NULL)
return root;
TreeNode*cur=root;
int sum=0;
while(cur!=NULL||!stk.empty())
{
if(cur!=NULL)
{
stk.push(cur);
cur=cur->right;
}
else
{
cur=stk.top();
stk.pop();
sum+=cur->val;
cur->val=sum;
cur=cur->left;
}
}
return root;
}
思路三:Morris 遍历
Morris 遍历的详解见链接: https://www.cnblogs.com/zhangbochao/p/12796561.html
题目为啥可以采用Morris 遍历,后续讲解