leetcode-919:完全二叉树插入器

简介: leetcode-919:完全二叉树插入器

题目

题目连接

完全二叉树 是每一层(除最后一层外)都是完全填充(即,节点数达到最大)的,并且所有的节点都尽可能地集中在左侧。

设计一种算法,将一个新节点插入到一个完整的二叉树中,并在插入后保持其完整。

实现 CBTInserter 类:

CBTInserter(TreeNode root) 使用头节点为 root 的给定树初始化该数据结构;

CBTInserter.insert(int v) 向树中插入一个值为 Node.val == val的新节点 TreeNode。使树保持完全二叉树的状态,并返回插入节点 TreeNode 的父节点的值;

CBTInserter.get_root() 将返回树的头节点。

示例 1:

输入
["CBTInserter", "insert", "insert", "get_root"]
[[[1, 2]], [3], [4], []]
输出
[null, 1, 2, [1, 2, 3, 4]]
解释
CBTInserter cBTInserter = new CBTInserter([1, 2]);
cBTInserter.insert(3);  // 返回 1
cBTInserter.insert(4);  // 返回 2
cBTInserter.get_root(); // 返回 [1, 2, 3, 4]

解题

方法一:双队列—O(1)复杂度插入

如果每次插入的时候都进行层序遍历,那么如果在插入情况比较多的时候,效率会很低。

如果能直接从队列中取出节点,然后插入,那么就会快很多。

由于是完美二叉树,被插入的节点,只可能是2种状态

  1. 没有左、右子节点, 这种情况下后续是先插入左节点
  2. 有左子节点,没右子节点,这种情况下,插入右节点

初始化的时候将情况1,存储在q_L队列中,将情况2,存储在q_R队列中。

因此可以通过层序遍历,初始化q_L,q_R队列

由于完全二叉树的特性,插入的时候,优先从q_R队列中取值。

/**
 * 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 CBTInserter {
public:
    TreeNode* root;
    queue<TreeNode*> q_L;//存放没有左右孩子的节点
    queue<TreeNode*> q_R;//存放没有右孩子的节点
    CBTInserter(TreeNode* root) {//目的是为了初始化q_L和q_R队列
        this->root=root;
        queue<TreeNode*> q;
        q.push(root);
        while(!q.empty()){
            TreeNode* cur=q.front();
            q.pop();
            if(!cur->left&&!cur->right) q_L.push(cur);
            if(cur->left&&!cur->right) q_R.push(cur);
            if(cur->left) q.push(cur->left);
            if(cur->right) q.push(cur->right);
        }
    }
    int insert(int val) {
        if(!q_R.empty()){//优先取仅没有右孩子的节点(因为完全二叉树的特点)
            TreeNode* cur=q_R.front();
            q_R.pop();
            cur->right=new TreeNode(val);
            q_L.push(cur->right);
            return cur->val;
        }
        else{//取没有左右孩子的节点
            TreeNode* cur=q_L.front();
            q_L.pop();
            cur->left=new TreeNode(val);
            q_R.push(cur);
            q_L.push(cur->left);
            return cur->val;
        }
    }
    TreeNode* get_root() {
        return root;
    }
};

方法二:插入时–层序遍历

class CBTInserter {
public:
    TreeNode* root;
    CBTInserter(TreeNode* root) {
        this->root=root;
    }
    int insert(int val) {
        queue<TreeNode*> q;
        q.push(root);
        while(!q.empty()){
            TreeNode* cur=q.front();
            q.pop();
            if(cur->left) q.push(cur->left);
            else{
                cur->left=new TreeNode(val);
                return cur->val;
            }
            if(cur->right) q.push(cur->right);
            else{
                cur->right=new TreeNode(val);
                return cur->val;
            }
        }
        return -1;
    }
    TreeNode* get_root() {
        return root;
    }
};

方法三:单队列—O(1)复杂度插入

其实和方法一几乎是一样的,但是方法一可以改进。

因为是完全二叉树的特点,因为必定可能保证,优先把只有左叶子节点的节点的取出来,然后才会取没有左右节点的叶子节点。

class CBTInserter {
public:
    queue<TreeNode*> q;
    TreeNode* root;
    CBTInserter(TreeNode* root) {
        this->root=root;
        queue<TreeNode*> q_tmp;
        q_tmp.push(root);
        while(!q_tmp.empty()){
            TreeNode* cur=q_tmp.front();
            q_tmp.pop();
            if(!cur->left||!cur->right) q.push(cur);
            if(cur->left) q_tmp.push(cur->left);
            if(cur->right) q_tmp.push(cur->right);
        }
    }
    int insert(int val) {
        TreeNode* cur=q.front();
        if(cur->left){
            cur->right=new TreeNode(val);
            q.pop();
            q.push(cur->right);
        }
        else{
            cur->left=new TreeNode(val);
            q.push(cur->left);
        }
        return cur->val;
    }
    TreeNode* get_root() {
        return root;
    }
};
相关文章
|
6月前
|
算法 vr&ar 图形学
☆打卡算法☆LeetCode 222. 完全二叉树的节点个数 算法解析
☆打卡算法☆LeetCode 222. 完全二叉树的节点个数 算法解析
|
6月前
|
Java C++ Python
leetcode-222:完全二叉树的节点个数
leetcode-222:完全二叉树的节点个数
27 0
|
3月前
|
Python
【Leetcode刷题Python】222. 完全二叉树的节点个数
LeetCode第222题"完全二叉树的节点个数"的Python代码实现,通过递归和深度优先遍历的方法来计算给定完全二叉树的节点总数。
33 5
代码随想录 Day13 二叉树 LeetCode T104 二叉树的最大深度 T111 二叉树的最小深度 T222完全二叉树的节点个数
代码随想录 Day13 二叉树 LeetCode T104 二叉树的最大深度 T111 二叉树的最小深度 T222完全二叉树的节点个数
56 0
|
6月前
leetcode代码记录(完全二叉树的节点个数
leetcode代码记录(完全二叉树的节点个数
29 1
LeetCode刷题Day14——二叉树(完全二叉树、平衡二叉树、二叉树路径、左叶子之和)
一、完全二叉树的节点个数 题目链接:222. 完全二叉树的节点个数
|
12月前
|
算法
代码随想录算法训练营第十五天 | LeetCode 104. 二叉树的最大深度、559. N 叉树的最大深度、111.二叉树的最小深度、222. 完全二叉树的节点个数
代码随想录算法训练营第十五天 | LeetCode 104. 二叉树的最大深度、559. N 叉树的最大深度、111.二叉树的最小深度、222. 完全二叉树的节点个数
53 0
|
算法 开发工具 git
LeetCode算法小抄-- 最近公共祖先 和 完全二叉树的节点个数
LeetCode算法小抄-- 最近公共祖先 和 完全二叉树的节点个数
|
算法
LeetCode每日一题--完全二叉树的节点个数
LeetCode每日一题--完全二叉树的节点个数
80 0
|
算法
力扣222.完全二叉树的节点个数
力扣222.完全二叉树的节点个数
63 0