12 力扣热题刷题记录之第102题二叉树的层序遍历

系列文章目录

力扣刷题记录

文章目录

  • 系列文章目录
  • 前言
  • 一、背景
  • 二、我的思路
  • 三、官方的思路
  • 总结

前言

每天进步一点点!!

一、背景

给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
12 力扣热题刷题记录之第102题二叉树的层序遍历_第1张图片

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal

二、我的思路

咋一看,这个挺简单的,用队列就能做。仔细一做,我丢,怎么是返回一个二维数组,还是vector的,本身对stL 库不是很熟悉,这下。。。

先是想着,把这些东西存放到一维数组里面,然后空值就给它设置为INT_MAX,然后遍历这个一维数组,按照满二叉树的办法。如果遇到INT_MAX,就不放入二维数组。但是吧,这个有点复杂,不想这样做。

艾,评论有说递归,给了一个深度的参数,进行传递,又有评论提到哈希表,哈哈。直接用哈希存储键值对不就行了。如果深度值捕大鱼vector数组的行数,那么就是在同一层。

好啦,代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
     
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
     
        //迭代法尝试 计时17:01 截止:18:29

        //存储返回值,先考虑一维数组
        vector<vector<int> > my_ans={
     };
        map<TreeNode*,int> depth;//map维护结点的深度信息
        //考虑用队列维护
        queue<TreeNode*> que;
        if(root!=nullptr)
        {
     
            que.push(root);
            depth[root]=0;//根节点在第零层
        }
        else return{
     };

        int i=0;
        my_ans.push_back(vector<int>());
        //循环,队列不空,初始时为树不空
        while(!que.empty())
        {
            
            //考虑出队
            if(depth[root]>i) 
            {
     
                //深度大于i,数组层数,那么增加
                my_ans.push_back(vector<int>());
                i++;
            }
            my_ans[depth[root]].push_back(root->val);

            que.pop();//队首元素出队

            //左右孩子不空的话,加入队列  
            if(root->left!=nullptr)
            {
     
                que.push(root->left);
                depth[root->left]=depth[root]+1;
            }
            if(root->right!=nullptr)
            {
     
                que.push(root->right);
                depth[root->right]=depth[root]+1;
            }
            root=que.front();
        }  
        return my_ans;       
    }
};

三、官方的思路

官方倒好,以来就说哈希表,但是为了追求更高的效率(更低的空间复杂度),毅然决然给了另一种办法,还给了证明。

我一想,这我看得懂,干脆直接读代码,我发现,妙啊!

它是这么干的。首先,层次不分明主要在于当前层的元素还没完全存入二维数组里面,新的层的元素又来了,不好区分。搞明白这个点,他就用循环,这个循环结束便是当前层的所有元素。那么为什么能这样呢?

主要是人循环的结束条件是在此之前计算了队列内元素的个数。等会,此是什么情况?简单来说,就是上一层的元素刚出栈,这一层的元素刚入栈的时候,计算队内元素数量,这简直不要太牛逼!!!

代码如下:

class Solution {
     
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
     
        vector <vector <int>> ret;
        if (!root) {
     
            return ret;
        }

        queue <TreeNode*> q;
        q.push(root);
        while (!q.empty()) {
     
            int currentLevelSize = q.size();
            ret.push_back(vector <int> ());
            for (int i = 1; i <= currentLevelSize; ++i) {
     
                auto node = q.front(); q.pop();
                ret.back().push_back(node->val);
                if (node->left) q.push(node->left);
                if (node->right) q.push(node->right);
            }
        }
        
        return ret;
    }
};

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/solution/er-cha-shu-de-ceng-xu-bian-li-by-leetcode-solution/
来源:力扣(LeetCode)

注意一个细节,for循环之前,vector数组是有申请一维数组的长度,简单来讲就是申请了行。但是下面这个是指在最后面的元素开始加入元素,那怎么知道是加在了下一行呢?(搞不太懂)

ret.back().push_back(node->val);

相比之下,我喜欢这种写法:

my_ans[depth].push_back(root->val);

总结

看了好些别人刷题的经验,关于做笔记这件事,好像近乎执着,就是尽可能的优化。但是我虽然也是这么想的,可是更多时候还是懒一点,不远多去查点资料,把某一部分写的更深入更细致一点,这也是我为啥不上不下的原因把!

另外就是,现在打算开始按label刷题了,之前想着按照给定的题目顺序来着,或是按照难易层度来着,说是这样不利于对一类题搞懂,不利于自己的总结。

喜欢就来个赞叭!!

(别走,关注也行

你可能感兴趣的:(力扣刷题记录,leetcode,树结构,队列)