题目
力扣
思路一 反序中序遍历
先遍历右子树,再访问根节点,最后遍历左子树,用变量记录下当前遍历到的节点的和。
代码一
class Solution {
public:
int res = 0;
TreeNode* convertBST(TreeNode* root) {
if(root){
convertBST(root->right);
res += root->val;
root->val = res;
convertBST(root->left);
}
return root;
}
};
思路二 Morris 遍历
- 如果当前节点的右子节点为空,处理当前节点,并遍历当前节点的左子节点。
- 如果当前节点的右子节点不为空,找到当前节点右子树的最左节点(该节点为当前节点中序遍历的前驱节点)。
- 如果最左节点的左指针为空,将最左节点的左指针指向当前节点,遍历当前节点的右子节点。
- 如果最左节点的左指针不为空,将最左节点的右指针重新置为空(恢复树的原状),处理当前节点,并将当前节点置为其左节点。
代码二
class Solution {
public:
TreeNode* convertBST(TreeNode* root) {
int sum = 0;
TreeNode* cur = root;
while(cur){
TreeNode* pre = cur->right;
if(pre){
while(pre->left != nullptr && pre->left !=cur)
pre = pre->left;
if(pre->left == nullptr){
pre->left = cur;
cur = cur->right;
continue;
}else{
pre->left = nullptr;
}
}
sum += cur->val;
cur->val = sum;
cur = cur->left;
}
return root;
}
};