天哪这道题大有文章哈哈哈哈哈哈哈
题目里面很重要的一点是二叉搜索树,而我对这一点完全没有在意…
二叉搜索树是左儿子小于自己,右儿子大于自己,左右子树又都满足这个条件的一棵树。那么知道这个之后就能发现如果反向中序遍历,得到的就是一个由大到小的序列,直接累加求前缀和就行了。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void bianli(TreeNode *t, int &sum)
{
if (t->right)
{
bianli(t->right, sum);
}
sum += t->val;
t->val = sum;
if (t->left)
{
bianli(t->left, sum);
}
}
TreeNode* convertBST(TreeNode* root) {
if (root == NULL) return root;
int sum = 0;
bianli(root, sum);
return root;
}
};
需要注意的是sum的值是一定要传引用过去的,我们需要它的值不断改变【这里我不知道有没有个设全局变量的方法也能解决这个问题…但总之需要修改值的时候传引用】,所以我们调用函数的时候就不能直接bianli(root, 0)
这里0 和int&不是一种类型。
And一定要记得特判树为空的情况!!!
下面是我不知道二叉搜索树的性质的时候写的代码,T了,但是也不失为一中办法_(:з」∠)_
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void leijia(TreeNode *t, map<int, int> &m, vector<int> &sum)
{
m[t->val] = 0;
sum.push_back(t->val);
if (t->left) leijia(t->left, m, sum);
if (t->right) leijia(t->right, m, sum);
}
void fuzhi(TreeNode *t, map<int, int> m)
{
// map<int, int>::iterator r; //要注意iterator需要这样声明
// r = m.find(t->val);
// t->val = r->second; //这几行好傻hhh 用下面一行就可以代替了
t->val = m[t->val];
if (t->left) fuzhi(t->left, m);
if (t->right) fuzhi(t->right, m);
}
TreeNode* convertBST(TreeNode* root) {
if (root == NULL) return root;
map<int, int> m;
vector<int> sum;
leijia(root, m, sum);
sort(sum.begin(), sum.end(), greater<int>()); //greater这里需要加括号,因为是函数
int size = sum.size();
// for (int i = 0; i < size; i++)
// {
// printf("%d ", sum[i]);
// }
// printf("\n");
int newV = 0;
for (int i = 0; i < size; i++)
{
newV += sum[i];
m[sum[i]] = newV;
//printf("%d ", m[sum[i]]);
}
fuzhi(root, m);
return root;
}
};