博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LeetCode 538. Convert BST to Greater Tree 解题报告
阅读量:2359 次
发布时间:2019-05-10

本文共 2454 字,大约阅读时间需要 8 分钟。

LeetCode 538. Convert BST to Greater Tree 解题报告

题目描述

Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus sum of all keys greater than the original key in BST.


示例

Example 1:

Example1


注意事项

没有给出.


解题思路

我的思路:

题目的意思是给出一个二分查找树,更改里面的节点值,使得更改后的节点值为原来的节点加上所有比它大的节点的值。比如例子中的节点5,因为只有节点13比它大,所以更改的值为5+13=18,而对于节点2,因为节点5和节点13都比它大,所以更改的值为2+5+13=20。

题目看起来似乎蛮复杂的,最笨的方法就是对于某一个节点得找出所有比它大的节点,然后把值相加。但是这其中有很多重复的工作,同时也没有利用好题目给出的是二分查找树这一条件。

二分查找树的特点是中序遍历的结果是一个升序序列。而我们做加法时最简单的顺序就是从最大的值开始,降序地做下去。在树中对应的就是最右的叶子节点开始,因为该节点是最大的。如果对二分查找树有一定的敏感度的话,应该很容易就发现一个性质:如果我们按照中序遍历的逆序,即先右子节点,再父节点,最后左子节点顺序遍历的话,刚好就能降序地访问每一个节点。比如例子中就会是以13,5,2的顺序访问,这样我们每访问一个节点,就记录下到该节点的和,并在访问下一节点时将该和值加到节点的值上。以例子说明:

初始sum为0。
访问到13,更新节点值为13+sum=13+0=13,sum更新为sum+13=0+13=13;
访问到5,更新节点值为5+sum=5+13=18,sum更新为sum+5=13+5=18;
访问到2,更新节点值为2+sum=2+18=20,sum更新为sum+2=18+2=20;

因此,题目其实考的就是BST中序对应的逆序遍历,先访问右子树,然后父节点,最后左子树,并在访问过程中记录已访问的节点总和,累加到当前的节点上。见下面我的代码。

参考思路:

通过之后看了一下其他大神的解法,关键的地方就是逆中序遍历,不同的可能就是和值的处理,我上面的过程中就绕了一下,其中从我举的例子就能看到sum和更新的节点是一样,真正正确的理解应该是更新后的节点值是逆中序遍历中包含该节点的所有已访问节点的和值。下面参考代码就是体现这一点。


代码

我的代码:

/** * 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 dfs(TreeNode *root, int &sum) {        if (root->right)            dfs(root->right, sum);        int temp = root->val;        root->val += sum;        sum += temp;        if (root->left)            dfs(root->left, sum);    }    TreeNode* convertBST(TreeNode* root) {        if (root) {            int sum = 0;            dfs(root, sum);        }        return root;    }};

参考代码:

/** * 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 {private:    int cur_sum = 0;public:    void travel(TreeNode* root){        if (!root)             return;        if (root->right)             travel(root->right);        root->val = (cur_sum += root->val);        if (root->left)             travel(root->left);    }    TreeNode* convertBST(TreeNode* root) {        travel(root);        return root;    }};

总结

这道题很不错,很高兴自己能够在大概10分钟左右做出来。以前关于BST,第一反应是中序结果为递增序列,通过做这道题,我自己想到了逆中序遍历的结果就是递减序列,一下子有种豁然开朗的感觉。对于常见的数据结构应该就要这样灵活运用,平时就得多做题多去思考,厚积薄发。

终于把进度赶回来,下一周加油!继续做其他课程的项目中,如果有时间会写写最近自己做的小项目,加油加油~

你可能感兴趣的文章
【在线研讨】《敏捷开发用户故事分类与组织结构(一期)》2012-06-26(周二)
查看>>
《火星人开发纪实:敏捷开发一千零一夜》序言
查看>>
《火星人开发纪实:敏捷开发一千零一夜》第一个月:一个产品的诞生
查看>>
《火星人开发纪实:敏捷开发一千零一夜》第二个月:框架优先,还是故事群优先
查看>>
敏捷开发松结对编程系列之十:代码审查最佳实践
查看>>
免费敏捷开发管理工具:火星人
查看>>
火星人网站开通,开放注册中 http://www.scrum.org.cn/
查看>>
敏捷开发用户故事系列之八:剖析用户故事描述语法(兼谈不同种类故事的语法)
查看>>
敏捷开发用户故事系列之九:用户故事早期估算
查看>>
《火星人敏捷开发手册2012-08-15》版发布:用户故事分类及示例
查看>>
【在线研讨】《敏捷开发用户故事分类与组织结构(三期)》2012-08-28(周二)
查看>>
敏捷开发“松结对编程”系列之十:L型代码结构(技术篇之一)
查看>>
敏捷开发“松结对编程”系列之十一:L型代码结构(团队篇之一)
查看>>
陈旧语法密度之七——用泛型消灭if-else if-else
查看>>
陈旧语法密度之三——用直接删除else的方法消除if-else if-else
查看>>
陈旧语法密度之五——用三元表达式消灭if-else if-else
查看>>
ImageView的缩放模式ScaleType
查看>>
用javadoc命令生成api帮助文档
查看>>
MBR简介
查看>>
查看Linux内核版本号与发行版本号
查看>>