[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 ...
随机推荐
- Javal连载4-注释&class与public class区别
一.Java注释 1.作用:不会编译倒.class文件之中:增强可读性 2.分类: (1)单行注释(只注释当前行):// (2)多行注释: /* 注释 注释 注释 */ (3)javadoc注释 /* ...
- Apache Maven 3.6.3配置安装
1.maven 3.5 下载地址:http://maven.apache.org/download.cgi 2.下载了解压到 3.配置环境变量 4.测试看是否安装成功 5.maven配置(全局配置,用 ...
- 【shell脚本】通过位置变量创建Linux账户及密码===addUser.sh
通过位置变量创建Linux账户及密码 脚本内容 [root@VM_0_10_centos shellScript]# vi addUser.sh #!/bin/bash # 通过位置变量创建系统账户及 ...
- Docker安装使用以及mlsql的docker安装使用说明
1.检查内核版本,必须是3.10及以上 uname -r 2.安装 yum -y install docker #1.启动 docker systemctl start docker #1.1.验 ...
- Linux SELinux 使用操作
Linux SELinux 使用操作 # 修改 SELinux 启动模式.临时生效 命令:setenforce [0|1] 0:转成 permissive 宽容模式: 1:转成 Enforcing 强 ...
- 深入浅出《设计模式》之简单工厂模式(C++)
前言 模式介绍 简单工厂模式其实并不属于GoF23(23种设计模式),更类似工厂模式的一种变型.其定义是可以根据参数的不同返回不同类的实例.简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实 ...
- VS2010 报错该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
尤其代码是从linux平台复制过来: 报错如图: 更有甚者基本函数都报错: 当下检查发现if else break case等基本函数并无问题时,报错行数明显不一致等一定要注意文档编码格式, 最简单的 ...
- 最新版windows安装支持输入shell命令的工具cygwin教程
首先去官网下载自己对应系统32位或64位系统版本安装包:https://cygwin.com/install.html 下载好后按提示一步一步安装,直到这一步: 初次安装,这里是空的,没有下载的镜像链 ...
- flink 批量梯度下降算法线性回归参数求解(Linear Regression with BGD(batch gradient descent) )
1.线性回归 假设线性函数如下: 假设我们有10个样本x1,y1),(x2,y2).....(x10,y10),求解目标就是根据多个样本求解theta0和theta1的最优值. 什么样的θ最好的呢?最 ...
- [PHP] 广度优先搜索匹配网站所有链接
<?php define('PRE_DOMAIN','www'); define('DOMAIN','sina.com.cn'); define('PROTOCOL','https'); def ...