题目:二叉树之字形层序遍历
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] ]
题意:
给定一个二叉树,返回按之字形层序遍历的每个节点的值。(即,从左到右,之后下一层从右到左,之后一直在两者之间交替进行)。
思路一:
采用递归实现,每次一层一层的完成递归,根据设置的left_to_right来进行从左到右,还是从右到左进行切换存入。时间复杂度O(n),空间复杂度O(n)。
代码:C++版:4ms
/** * 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: vector<vector<int>> zigzagLevelOrder(TreeNode* root) { vector<vector<int>> res; traverse(root, 1, res, true); return res; } void traverse(TreeNode *root, int level, vector<vector<int>> &res, bool left_to_right) { if (!root) return ; if (level > res.size()) //到新的一层,添加一个vector集合 res.push_back(vector<int>()); if (left_to_right) res[level-1].push_back(root->val); //从左到右直接将值添加在后面 else res[level-1].insert(res[level-1].begin(), root->val); //从右到左,每次插入到vector开始的位置 traverse(root->left, level+1, res, !left_to_right); //递归左子树 traverse(root->right, level+1, res, !left_to_right); //递归右子树 } };
思路二:
使用迭代实现。借助辅助队列实现广度优先遍历,当队列第一个值不为空指针时,将节点值放入level数组中,并将左右子节点放入队列中,如果第一个值为空指针,说明该层遍历结束,则利用left_to_right判断是否需要将level数组取反放入返回值集合中,用一个left_to_right记录是从左到右还是从右到左,每一层结束就翻转一下。时间复杂度O(n),空间复杂度O(n)。
代码:C++版:4ms
/** * 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: vector<vector<int>> zigzagLevelOrder(TreeNode* root) { vector<vector<int>> res; if (nullptr == root) return res; queue<TreeNode*> q; //辅助队列,实现广度优先遍历 bool left_to_right = true; vector<int> level; q.push(root); q.push(nullptr); while (!q.empty()) { TreeNode *cur = q.front(); //取队列第一个节点 q.pop(); if (cur) { level.push_back(cur->val); if (cur->left) q.push(cur->left); if (cur->right) q.push(cur->right); } else { if (left_to_right) { //实现左右切换 res.push_back(level); } else { reverse(level.begin(), level.end()); res.push_back(level); } level.clear(); //清空level数组,为下一层遍历做准备 left_to_right = !left_to_right; //左右交替 if (q.size() > 0) q.push(nullptr); //使用nullptr空指针代表这一层所有节点结束 } } return res; } };
思路三:转载:http://www.cnblogs.com/grandyang/p/4297009.html
利用栈实现。利用栈的后进先出的特点,这道题我们维护两个栈,相邻两行分别存到两个栈中,进栈的顺序也不相同,一个栈是先进左子结点然后右子节点,另一个栈是先进右子节点然后左子结点,这样出栈的顺序就是我们想要的之字形了。
代码:C++版:4ms
/** * 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: vector<vector<int>> zigzagLevelOrder(TreeNode* root) { vector<vector<int>> res; if (!root) return res; stack<TreeNode*> s1; stack<TreeNode*> s2; s1.push(root); vector<int> out; while (!s1.empty() || !s2.empty()) { while (!s1.empty()) { //实现从左到右 TreeNode *cur = s1.top(); s1.pop(); out.push_back(cur->val); if (cur->left) s2.push(cur->left); if (cur->right) s2.push(cur->right); } if (!out.empty()) res.push_back(out); out.clear(); while (!s2.empty()) { //实现从右向左 TreeNode *cur = s2.top(); s2.pop(); out.push_back(cur->val); if (cur->right) s1.push(cur->right); if (cur->left) s1.push(cur->left); } if (!out.empty()) res.push_back(out); out.clear(); } return res; } };