[LeetCode] 919. Complete Binary Tree Inserter 完全二叉树插入器
A *complete* binary tree is a binary tree in which every level, except possibly the last, is completely filled, and all nodes are as far left as possible.
Write a data structure CBTInserter that is initialized with a complete binary tree and supports the following operations:
CBTInserter(TreeNode root)initializes the data structure on a given tree with head noderoot;CBTInserter.insert(int v)will insert aTreeNodeinto the tree with valuenode.val = vso that the tree remains complete, and returns the value of the parent of the insertedTreeNode;CBTInserter.get_root()will return the head node of the tree.
Example 1:
Input: inputs = ["CBTInserter","insert","get_root"], inputs = [[[1]],[2],[]]
Output: [null,1,[1,2]]
Example 2:
Input: inputs = ["CBTInserter","insert","insert","get_root"], inputs = [[[1,2,3,4,5,6]],[7],[8],[]]
Output: [null,3,4,[1,2,3,4,5,6,7,8]]
Note:
- The initial given tree is complete and contains between
1and1000nodes. CBTInserter.insertis called at most10000times per test case.- Every value of a given or inserted node is between
0and5000.
这道题说是让实现一个完全二叉树的插入器的类,之前也做过关于完全二叉树的题 [Count Complete Tree Nodes](http://www.cnblogs.com/grandyang/p/4567827.html)。首先需要搞清楚的是完全二叉树的定义,即对于一颗二叉树,假设其深度为d(d>1)。除了第d层外,其它各层的节点数目均已达最大值,且第d层所有节点从左向右连续地紧密排列,换句话说,完全二叉树从根结点到倒数第二层满足完美二叉树,最后一层可以不完全填充,其叶子结点都靠左对齐。由于插入操作要找到最后一层的第一个空缺的位置,所以很自然的就想到了使用层序遍历的方法,由于插入函数返回的是插入位置的父结点,所以在层序遍历的时候,只要遇到某个结点的左子结点或者右子结点不存在,则跳出循环,则这个残缺的父结点刚好就在队列的首位置。那么在插入函数时,只要取出这个残缺的父结点,判断若其左子结点不存在,说明新的结点要连接在左子结点上,否则将新的结点连接在右子结点上,并把此时的左右子结点都存入队列中,并将之前的队首元素移除队列即可,参见代码如下:
解法一:
class CBTInserter {
public:
CBTInserter(TreeNode* root) {
tree_root = root;
q.push(root);
while (!q.empty()) {
auto t = q.front();
if (!t->left || !t->right) break;
q.push(t->left);
q.push(t->right);
q.pop();
}
}
int insert(int v) {
TreeNode *node = new TreeNode(v);
auto t = q.front();
if (!t->left) t->left = node;
else {
t->right = node;
q.push(t->left);
q.push(t->right);
q.pop();
}
return t->val;
}
TreeNode* get_root() {
return tree_root;
}
private:
TreeNode *tree_root;
queue<TreeNode*> q;
};
下面这种解法缩短了建树的时间,但是极大的增加了插入函数的运行时间,因为每插入一个结点,都要从头开始再遍历一次,并不是很高效,可以当作一种发散思维吧,参见代码如下:
解法二:
class CBTInserter {
public:
CBTInserter(TreeNode* root) {
tree_root = root;
}
int insert(int v) {
queue<TreeNode*> q{{tree_root}};
TreeNode *node = new TreeNode(v);
while (!q.empty()) {
auto t = q.front(); q.pop();
if (t->left) q.push(t->left);
else {
t->left = node;
return t->val;
}
if (t->right) q.push(t->right);
else {
t->right = node;
return t->val;
}
}
return 0;
}
TreeNode* get_root() {
return tree_root;
}
private:
TreeNode *tree_root;
};
再来看一种不使用队列的解法,因为队列总是要遍历,比较麻烦,如果使用数组来按层序遍历的顺序保存这个完全二叉树的结点,将会变得十分的简单。而且有个最大的好处是,可以直接通过坐标定位到其父结点的位置,通过 (i-1)/2 来找到父结点,这样的话就完美的解决了插入函数要求返回父结点的要求,而且通过判断当前完整二叉树结点个数的奇偶,可以得知最后一个结点是在左子结点上还是右子结点上,这样就可以直接将新加入的结点连到到父结点的正确的子结点位置,参见代码如下:
解法三:
class CBTInserter {
public:
CBTInserter(TreeNode* root) {
tree.push_back(root);
for (int i = 0; i < tree.size(); ++i) {
if (tree[i]->left) tree.push_back(tree[i]->left);
if (tree[i]->right) tree.push_back(tree[i]->right);
}
}
int insert(int v) {
TreeNode *node = new TreeNode(v);
int n = tree.size();
tree.push_back(node);
if (n % 2 == 1) tree[(n - 1) / 2]->left = node;
else tree[(n - 1) / 2]->right = node;
return tree[(n - 1) / 2]->val;
}
TreeNode* get_root() {
return tree[0];
}
private:
vector<TreeNode*> tree;
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/919
类似题目:
参考资料:
https://leetcode.com/problems/complete-binary-tree-inserter/
[LeetCode All in One 题目讲解汇总(持续更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)
[LeetCode] 919. Complete Binary Tree Inserter 完全二叉树插入器的更多相关文章
- LeetCode 919. Complete Binary Tree Inserter
原题链接在这里:https://leetcode.com/problems/complete-binary-tree-inserter/ 题目: A complete binary tree is a ...
- 【LeetCode】919. Complete Binary Tree Inserter 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址: https://leetcode. ...
- leetcode_919. Complete Binary Tree Inserter_完全二叉树插入
https://leetcode.com/problems/complete-binary-tree-inserter/ 给出树节点的定义和完全二叉树插入器类的定义,为这个类补全功能.完全二叉树的定义 ...
- [Swift]LeetCode919. 完全二叉树插入器 | Complete Binary Tree Inserter
A complete binary tree is a binary tree in which every level, except possibly the last, is completel ...
- PAT 1110 Complete Binary Tree[判断完全二叉树]
1110 Complete Binary Tree(25 分) Given a tree, you are supposed to tell if it is a complete binary tr ...
- leetcode_919. Complete Binary Tree Inserter
https://leetcode.com/problems/complete-binary-tree-inserter/ 设计一个CBTInserter,使用给定完全二叉树初始化.三个功能; CBTI ...
- PAT A1110 Complete Binary Tree (25 分)——完全二叉树,字符串转数字
Given a tree, you are supposed to tell if it is a complete binary tree. Input Specification: Each in ...
- [二叉树建树&完全二叉树判断] 1110. Complete Binary Tree (25)
1110. Complete Binary Tree (25) Given a tree, you are supposed to tell if it is a complete binary tr ...
- PAT甲级——1110 Complete Binary Tree (完全二叉树)
此文章同步发布在CSDN上:https://blog.csdn.net/weixin_44385565/article/details/90317830 1110 Complete Binary ...
随机推荐
- Leetcode算法题 7. Reverse Integer2
7. Reverse Integer 题目描述: Given a 32-bit signed integer, reverse digits of an integer. Example 1: Inp ...
- Jsp自学1
jsp学习之初,我是用记事本(EditPlus)来进行编辑的,那么写好的jsp文件如何执行看到效果呢?不像html文件可以直接用浏览器打开,jsp文件需要先进行编译器的编译才能执行,而Tomcat就可 ...
- IL 语法分析
Managed Heap: GC auto manage. One process, One heap. Call Stack: Runtime auto manage, every time whe ...
- telnet 发送邮件
telnet smtp.aliyun.com 25 // 这里用的是阿里云的smpt服务器,并且开放25端口 helo hi // 和阿里云的smtp服务器打招呼,测试是否连通 auth login ...
- C 储存类与运算符
储存类 参考链接:https://www.runoob.com/cprogramming/c-storage-classes.html 存储类定义 C 程序中变量/函数的范围(可见性)和生命周期 au ...
- java开发高校社团管理系统JSP
运行环境JDK1.7编写Eclipse( Neon.3 Release (4.6.3)) windows下Tomcat v8.5Mysql 5.5使用技术Java servlet & jspM ...
- Java自学-集合框架 ArrayList常用方法
ArrayList常用方法 步骤 1 : 增加 add 有两种用法: 第一种是直接add对象,把对象加在最后面 heros.add(new Hero("hero " + i)); ...
- Lucene BooleanQuery相关算法
BooleanQuery对两种不同查询场景执行不同的算法: 场景1: 所有的子句都必须满足,而且所有的子句里没有嵌套BooleanQuery. 例: a AND b AND c 上面语句表示要同时包含 ...
- web前端-框架jquery
1.jquery库 就是js的库 ,可以通过jquery语法简化js操作 ,如文档遍历 ,文档操作 ,事件处理 ,动画js定时器等等 2.引用 下载:https://www.bootcdn.cn/jq ...
- Linux下实现不活动用户登录超时后自动登出
方法一:通过修改.bashrc或.bash_profile文件来实现 通过修改home目录下的.bashrc或.bash_profile文件来实现.这两个文件选择其中一个在末尾加入如下一行,具体操作 ...