题目 反转二叉树的奇数层
难度 : 中等
- 题目大意 : 给定一个完美二叉数,让我们反转奇数层的数字
- 完美二叉树需满足:二叉树的所有父节点都有两个子节点,且所有叶子节点都在同一层
思路:
- 既然要反转,先遍历一遍,把所有的奇数层的节点的
val
全部记录一下,放到一个数组里面,之后再遍历一遍修改所有的奇数层的数 - 遍历二叉树, 下面代码用的是
dfs
,代码短一些,当然也可以使用bfs
,代码实现长一点,不过都可以写一写,练练手感 - 第二遍遍历怎么修改呢?
首先的想法 :遍历的时候要把这个节点的值改成对称位置的值,因为我们已经存好了对应奇数层的所有数,那么我们怎么找到对应的下标呢,我们一般来讲是记录下对应的下标,但是并不好记录这个信息,放弃这记录下标这个想法,那么还有什么方法吗?
正解 : 我们注意到如果我们是先dfs
左儿子, 那么每一层的数会从左往右依次记录在数组中,第二次遍历的时候,我们依旧是dfs
左儿子,每一层也是从左往右依次遍历到, 但是取值是从右边往左边取,那我们就可以遍历一个就把最后一个删掉,这样在下一次遍历到这一层的下一个节点时,刚好要修改的值就是数组中的最后一个值,这样问题就解决了!! - 本质上,仔细思考的话,我们可以发现,数组是从左往右存值,但是是从右往左取值,这不就是栈的思想吗,只不过是用数组的方式实现的
代码实现
class Solution {
public:
TreeNode* reverseOddLevels(TreeNode* root) {
vector<vector<int>> nums(15);
function<void(TreeNode*, int, bool)> dfs = [&](TreeNode* u, int dep, bool flag) -> void {
if (dep & 1) {
if (flag) {
nums[dep / 2].push_back(u->val);
} else {
int t = dep / 2;
u->val = nums[t].back();
nums[t].pop_back();
}
}
if (u->left) dfs(u->left, dep + 1, flag), dfs(u->right, dep + 1, flag);
};
dfs(root, 0, true), dfs(root, 0, false);
return root;
}
};
难点 :
- dfs实现
- 栈的思想
总结:
- 多思考,多敲代码才能真正提升
- 要有目的性的思考,这样思路会比较清晰
- 多借鉴优秀代码,学习新的思路
【微语】:人生短暂而珍贵,不要虚度光阴,用心去体验,用爱去感受,活出精彩人生
结束了!!!