经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
C++实现LeetCode(103.二叉树的之字形层序遍历)
来源:jb51  时间:2021/7/21 18:16:27  对本文有异议

[LeetCode] 103. Binary Tree Zigzag Level Order Traversal 二叉树的之字形层序遍历

Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between).

For example:
Given binary tree [3,9,20,null,null,15,7],

    3
/ \
9  20
/  \
15   7

return its zigzag level order traversal as:

[
[3],
[20,9],
[15,7]
]

这道二叉树的之字形层序遍历是之前那道 Binary Tree Level Order Traversal 的变形,不同之处在于一行是从左到右遍历,下一行是从右往左遍历,交叉往返的之字形的层序遍历。最简单直接的方法就是利用层序遍历,并使用一个变量 cnt 来统计当前的层数(从0开始),将所有的奇数层的结点值进行翻转一下即可,参见代码如下:

解法一:

  1. class Solution {
  2. public:
  3. vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
  4. if (!root) return {};
  5. vector<vector<int>> res;
  6. queue<TreeNode*> q{{root}};
  7. int cnt = 0;
  8. while (!q.empty()) {
  9. vector<int> oneLevel;
  10. for (int i = q.size(); i > 0; --i) {
  11. TreeNode *t = q.front(); q.pop();
  12. oneLevel.push_back(t->val);
  13. if (t->left) q.push(t->left);
  14. if (t->right) q.push(t->right);
  15. }
  16. if (cnt % 2 == 1) reverse(oneLevel.begin(), oneLevel.end());
  17. res.push_back(oneLevel);
  18. ++cnt;
  19. }
  20. return res;
  21. }
  22. };

我们可以将上面的解法进行优化一下,翻转数组虽然可行,但是比较耗时,假如能够直接计算出每个结点值在数组中的坐标,就可以直接进行更新了。由于每层的结点数是知道的,就是队列的元素个数,所以可以直接初始化数组的大小。此时使用一个变量 leftToRight 来标记顺序,初始时是 true,当此变量为 true 的时候,每次加入数组的位置就是i本身,若变量为 false 了,则加入到 size-1-i 位置上,这样就直接相当于翻转了数组。每层遍历完了之后,需要翻转 leftToRight 变量,同时不要忘了将 oneLevel 加入结果 res,参见代码如下:

解法二:

  1. class Solution {
  2. public:
  3. vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
  4. if (!root) return {};
  5. vector<vector<int>> res;
  6. queue<TreeNode*> q{{root}};
  7. bool leftToRight = true;
  8. while (!q.empty()) {
  9. int size = q.size();
  10. vector<int> oneLevel(size);
  11. for (int i = 0; i < size; ++i) {
  12. TreeNode *t = q.front(); q.pop();
  13. int idx = leftToRight ? i : (size - 1 - i);
  14. oneLevel[idx] = t->val;
  15. if (t->left) q.push(t->left);
  16. if (t->right) q.push(t->right);
  17. }
  18. leftToRight = !leftToRight;
  19. res.push_back(oneLevel);
  20. }
  21. return res;
  22. }
  23. };

我们也可以使用递归的方法来解,这里实际上用的是先序遍历,递归函数需要一个变量 level 来记录当前的深度,由于 level 是从0开始的,假如结果 res 的大小等于 level,就需要在结果 res 中新加一个空集,这样可以保证 res[level] 不会越界。取出 res[level] 之后,判断 levle 的奇偶,若其为偶数,则将 node->val 加入 oneLevel 的末尾,若为奇数,则加在 oneLevel 的开头。然后分别对 node 的左右子结点调用递归函数,此时要传入 level+1 即可,参见代码如下:

解法三:

  1. class Solution {
  2. public:
  3. vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
  4. vector<vector<int>> res;
  5. helper(root, 0, res);
  6. return res;
  7. }
  8. void helper(TreeNode* node, int level, vector<vector<int>>& res) {
  9. if (!node) return;
  10. if (res.size() <= level) {
  11. res.push_back({});
  12. }
  13. vector<int> &oneLevel = res[level];
  14. if (level % 2 == 0) oneLevel.push_back(node->val);
  15. else oneLevel.insert(oneLevel.begin(), node->val);
  16. helper(node->left, level + 1, res);
  17. helper(node->right, level + 1, res);
  18. }
  19. };

Github 同步地址:

https://github.com/grandyang/leetcode/issues/103

类似题目:

Binary Tree Level Order Traversal

参考资料:

https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/

https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/discuss/33815/My-accepted-JAVA-solution

https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/discuss/33825/c%2B%2B-5ms-version%3A-one-queue-and-without-reverse-operation-by-using-size-of-each-level

到此这篇关于C++实现LeetCode(103.二叉树的之字形层序遍历)的文章就介绍到这了,更多相关C++实现二叉树的之字形层序遍历内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号