1.把二叉树打印成多行
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
class Solution {
vector<vector<int> >res;
public:
vector<vector<int> > Print(TreeNode* pRoot) {
if(pRoot==nullptr)
return res;
int now=1,next=0;
vector<int> elem;
queue<TreeNode*> pNode;
pNode.push(pRoot);
while(!pNode.empty()){
TreeNode* tmp = pNode.front();
pNode.pop();
elem.push_back(tmp->val);
--now;
if(tmp->left){
pNode.push(tmp->left);
++next;
}
if(tmp->right){
pNode.push(tmp->right);
++next;
}
if(now==0){
now = next;
next = 0;
res.push_back(elem);
elem.clear();
}
}
return res;
}
};
2.序列化二叉树
请实现两个函数,分别用来序列化和反序列化二叉树
二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。
二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
private:
string assist;
public:
void seria(TreeNode *root){
if(root==nullptr){
assist +="#!";
return;
}
assist += to_string(root->val)+"!";
seria(root->left);
seria(root->right);
}
char* Serialize(TreeNode *root) {
seria(root);
char *str = new char[assist.size()];
strcpy(str,assist.c_str());
return str;
}
bool Readstream(char **str,int *data){
char *start = *str;
int num = 0;
if(*start=='#'){
start = start+2;
*str = start;
return false;
}
else if((*start)>='0'&&(*start)<='9'){
while((*start)>='0'&&(*start)<='9'){
num = num*10+(*start-'0');
++start;
}
if(*start == '!')
++start;
*data = num;
*str = start;
return true;
}
return false;
}
TreeNode* Deserialize(char **str) {
int num;
if(Readstream(str,&num)){
TreeNode *root = new TreeNode(num);
root->left = Deserialize(str);
root->right = Deserialize(str);
return root;
}
return nullptr;
}
TreeNode* Deserialize(char *str) {
return Deserialize(&str);
}
};
相对比较繁琐的一个程序,主要难点是反序列化,有一个小技巧就是要不断修改字符串的指针目前所指向的化就要使用二级指针,说了半天建树是小意思,玩指针才是主要目的呀!
3.二叉搜索树的第k个结点
给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。
class Solution {
int n;
int size=0;
TreeNode *p;
public:
void KthNode(TreeNode* pRoot)
{
if(pRoot==nullptr||n<1)
return;
KthNode(pRoot->left);
if(n==1) p=pRoot;
--n;
++size;
KthNode(pRoot->right);
}
TreeNode* KthNode(TreeNode* pRoot, int k)
{
if(pRoot==nullptr||k<=0)
return nullptr;
n = k;
KthNode(pRoot);
if(k>size)
return nullptr;
return p;
}
};
要考虑到K值大于节点数的情况
4.数据流中的中位数
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
class Solution {
private:
vector<int> min;
vector<int> max;
public:
void Insert(int num)
{//优先级,& < ==
if(((min.size()+max.size())&1)==0){
if(max.size()>0&&max[0]>num){
max.push_back(num);
push_heap(max.begin(),max.end());
num = max[0];
pop_heap(max.begin(),max.end());
max.pop_back();
}
min.push_back(num);
push_heap(min.begin(),min.end(),greater<int>());
}else{
if(min.size()>0&&min[0]<num){
min.push_back(num);
push_heap(min.begin(),min.end(),greater<int>());
num = min[0];
pop_heap(min.begin(),min.end(),greater<int>());
min.pop_back();
}
max.push_back(num);
push_heap(max.begin(),max.end());
}
}
double GetMedian()
{
int size = min.size()+max.size();
if(size == 0)
return -1;
if(size&1 == 1)
return min[0];
else
return (min[0]+max[0])/2.0;
}
};