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;
}
};