1. 中序遍历
BST的中序遍历得到的结果是从小到大的有序序列,可以使用一个数组记录这个序列,然后遍历BST,对每个节点累加值。
为了降低累加过程需要的时间,可以使用hash表统计大于各个值的节点值之和,从而避免每次都要重新求和。
时间O(n),空间O(n)。  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
   | class Solution { public:     TreeNode* convertBST(TreeNode* root) {         if (root == nullptr)             return root;
          vector<int> vals;         midOrder(root, vals);         unordered_map<int, int> sum;         int temp = 0;         for (int i = vals.size() - 1; i >= 0; i--) {             temp += vals[i];             sum[vals[i]] = temp;         }
          queue<TreeNode*> q;         q.push(root);         TreeNode* cur;         while (!q.empty()) {             cur = q.front();             q.pop();             cur->val = sum[cur->val];             if (cur->left != nullptr)                 q.push(cur->left);             if (cur->right != nullptr)                 q.push(cur->right);         }
          return root;     } private:     void midOrder(TreeNode* root, vector<int>& vals) {         stack<TreeNode*> st;         while (root != nullptr || !st.empty()) {             if (root == nullptr) {                 root = st.top();                 st.pop();                 vals.push_back(root->val);                 root = root->right;             } else {                 st.push(root);                 root = root->left;             }         }     } };
  | 
 
2. 反向中序遍历
要修改一个节点需要获取比这个节点大的值,比它大的值在它的右子树中,同时还来自于它的各层父节点(如果它是父节点的左孩子的话)。
如果按照这个思路求解每个节点的比它大的所有值是有些困难的,但是联想到中序遍历得到的有序序列就会比较简单。
中序左根右遍历BST得到的是由小到大的有序序列,因此反向中序右根左遍历BST得到的是由大到小的有序序列。
题目需要的比每个节点大的值正好由反向中序遍历提供了。
时间O(n),空间O(n)。  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | class Solution { public:     TreeNode* convertBST(TreeNode* root) {         TreeNode* keepRoot = root;         stack<TreeNode*> st;         int sum = 0;         while (root != nullptr || !st.empty()) {             if (root == nullptr) {                 root = st.top();                 st.pop();                 sum += root->val;                 root->val = sum;                 root = root->left;             } else {                 st.push(root);                 root = root->right;             }         }
          return keepRoot;     } };
  |