【AC笔记】0103.二叉树的锯齿形层序遍历

题目要求

  1. 返回其节点值的锯齿形层序遍历(也就是,如果第一层遍历顺序时从左到右,第二次遍历顺序就要从右到左,依次类推)

图解示例

在这里插入图片描述

算法思想

方法一:使用广度优先搜索 + 调整结果

  1. 本题比较简单的办法就是先使用广度优先搜索,即遍历到哪一层,都按从左到右的顺序放入列表中
  2. 完成遍历后,对偶数层(即下标为单数的 ans[i])的遍历结果,倒转顺序

方法二:使用栈+列表

  1. 通过分析示例,我们发现,偶数层的遍历顺序与输出顺序刚好相反,即本来先遍历到的数据,后出现在列表中
  2. 使用栈(先进后出)的方式存储偶数层节点数据,当换到下一层的时候,依次 pop 出栈中的数据,放到分步

完整代码

方法一:使用广度优先搜索 + 调整结果

class Solution {
public:
    vector<vector<int> > zigzagLevelOrder(TreeNode* root) {
        vector<vector<int> > ans;
        if(root==NULL) return ans;
        // 分步结果 
        vector<int> temp;
        // 层数标记 
        int flag_layer = 1;
        // 广度优先搜索 
        queue<pair<TreeNode*, int> > q;
        q.push(make_pair(root,1));
        while(!q.empty()) {
        	pair<TreeNode*, int> p = q.front();
        	q.pop();
        	// 记录节点和层数
        	TreeNode* node = p.first;
        	int layer = p.second;
        	// 下一层时,需要将分步结果temp中的数据放入ans中,并重置分步结果temp,用来存储新一层的数据
        	if(layer!=flag_layer) {
        		ans.push_back(temp);
        		temp.clear();
        		flag_layer = layer;
			}
        	temp.push_back(node->val);
            // 继续广度遍历
        	if(node->left) {
        		q.push(make_pair(node->left,layer + 1));
			}
			if(node->right) {
				q.push(make_pair(node->right,layer+1));
			}
			int size = q.size();
		}
        // 最后一层的分步结果加入ans
		ans.push_back(temp);
        // 将下标为奇数的ans中的对应表列表中的数据倒转
		for(int i = 1; i < ans.size(); i+=2) {
			int len =  ans[i].size();
			for(int j = 0; j < len/2; j++) {
				int temp = ans[i][j];
				ans[i][j] = ans[i][len-1-j];
				ans[i][len-1-j] = temp;
			}
		}
		return ans;
    }
};

方法二:使用栈+列表

class Solution {
public:
    vector<vector<int> > zigzagLevelOrder(TreeNode* root) {
        vector<vector<int> > ans;
        if(root==NULL) return ans;
        // 分步结果 
        vector<int> temp;
        // 记录偶数层数据
        stack<int> even_stack;
        // 广度优先搜索 
        queue<pair<TreeNode*, int> > q;
        //标记层数 
        int layer_flag = 1;
        q.push(make_pair(root,1));
        while(!q.empty()) {
        	pair<TreeNode*, int> p = q.front();
        	q.pop();
        	TreeNode* node = p.first;
        	int layer = p.second;
            // 下一层时,需要将分步结果temp/even_stack中的数据放入ans中,并重置分步结果temp/even_stack,
            // 用来存储新一层的数据
        	if(layer!=layer_flag) {
        		while(!even_stack.empty()) {
        			temp.push_back(even_stack.top());
        			even_stack.pop();
				} 
        		ans.push_back(temp);
        		temp.clear();
        		layer_flag = layer; 
			}
			// 判断当前层需要用到哪一种数据结构存储 
			if(layer%2==0) {
        		even_stack.push(node->val);
			} else {
				temp.push_back(node->val);
			}
            // 继续广度遍历
        	if(node->left) {
        		q.push(make_pair(node->left,layer + 1));
			}
			if(node->right) {
				q.push(make_pair(node->right,layer+1));
			}
			
		}
        // 最后一层的分步结果加入ans
		if(layer_flag%2==0) {
			while(!even_stack.empty()) {
    			temp.push_back(even_stack.top());
    			even_stack.pop();
			} 
			ans.push_back(temp);
		} else{
			ans.push_back(temp);
		}
		return ans;
    }
};

设计分析

方法一:

时间复杂度:O(n+(logn)2/2)~o(n):n是指遍历整棵树,logn/2是指层数,logn指层数中的size

空间复杂度:O(2logn)~o(logn)需要一个队列,和分步结果队列

方法二:

时间复杂度:O(nlogn/2):n是指遍历整棵树,logn/2是指需要使用栈的层数

空间复杂度:O(3logn)~o(logn):需要一个队列,和分步结果队列,一个栈

提交结果

在这里插入图片描述

若有其他解法,欢迎评论区补充。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_之桐_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值