LeetCode 538-Convert BST to Greater Tree
LeetCode 1038-Binary Search Tree to Greater Sum Tree
题干:
把一棵BST转化为一棵累加树。对累加树的每个节点,该节点的值是BST中所有大于等于它的值之和。
解:
利用中序遍历得到有序数组的特性。
BST显然可通过中序遍历转化为一个升序序列,对序列中的每个元素,它在累加树中对应的值是这个升序序列的后缀和。
即,也可通过中序遍历转化为降序序列(只需改变递归顺序,先右),那么对于这个序列中的元素,它在累加树中对应的值是这个降序序列的前缀和,可通过访问的先后顺序累加得到。
方法1:递归
引入外部变量sum记录累加和,修改中序遍历的递归顺序(先右),从而降序遍历BST的值并进行累加。
int sum = 0; // 累加和
TreeNode* convertBST(TreeNode* root) {
traverse(root);
return root;
}
void traverse(TreeNode* root){
if(!root) return;
traverse(root->right);
sum += root->val; // 维护当前累加和
root->val = sum; // 把当前累加和赋给该节点
traverse(root->left);
}
方法2:迭代
如何迭代可参考“中序遍历的统一写法”。
注意入栈顺序需要改变。
int sum = 0; // 累加和
TreeNode* convertBST(TreeNode* root) {
traverse(root);
return root;
}
void traverse(TreeNode* root){
if(!root) return;
stack<TreeNode*> st;
st.push(root);
int sum = 0; // 累加和
while(!st.empty()){
TreeNode* t = st.top();
st.pop();
if(t){
if(t->left) st.push(t->left); //左
st.push(t); //中
st.push(nullptr);
if(t->right) st.push(t->right); //右
}
else{
t = st.top();
st.pop();
sum += t->val; // 维护当前累加和
t->val = sum; // 把当前累加和赋给该节点
}
}
}