(1)重建二叉树
上来就想递归就完事儿了
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
if(!pre.size()||!vin.size())return NULL;
int root=pre[0];
TreeNode * RootNode=new TreeNode(pre[0]);
auto vinroot=find(vin.begin(),vin.end(),root);
int lsize=vinroot-vin.begin();
int rsize=vin.end()-vinroot-1;
TreeNode* left=reConstructBinaryTree(vector<int>(pre.begin()+1,pre.begin()+1+lsize),
vector<int>(vin.begin(),vin.begin()+lsize));
TreeNode* right=reConstructBinaryTree(vector<int>(pre.begin()+1+lsize,pre.end()),
vector<int>(vinroot+1,vin.end()));
RootNode->left=left;
RootNode->right=right;
return RootNode;
}
};
(2)二叉树的镜像
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
void Mirror(TreeNode *pRoot) {
if(pRoot==NULL) return;
Mirror(pRoot->left);
Mirror(pRoot->right);
TreeNode * temp=pRoot->left;
pRoot->left=pRoot->right;
pRoot->right=temp;
}
};
一般来说这里用递归是显而易见的,但有时候面试官想考我们对于代码的转化能力,让把这个递归转化为非递归怎么办?
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
void Mirror(TreeNode *pRoot) {
if(pRoot==NULL) return;
queue<TreeNode *>que;
TreeNode* temp;
que.push(pRoot);
while(!que.empty())
{
temp=que.front()->left;
que.front()->left=que.front()->right;
que.front()->right=temp;
if(que.front()->left)
que.push(que.front()->left);
if(que.front()->right)
que.push(que.front()->right);
que.pop();
}
}
};
希望我的脑子可以转一转 啥时候都判断一下是不是NULL,真是三天两头错这种憨憨东西
(3)二叉树的后续遍历
每次看到二叉树就觉的指定又是递归,所以我们先按递归写一遍再说..
首先你要知道树可以空 二叉树不能空......我吐了我 二叉树不能看做树的分支 不是被包含的关系.因此
class Solution {
public:
bool judge(vector<int> seq,int start,int end){
if(start>=end)return true;
int k;
for(k=start;seq[k]<seq[end];k++)
{
}
for(int j=k;j<=end;j++)
{
if(seq[j]<seq[end])return false;
}
return judge(seq,start,k-1)&&judge(seq,k,end-1);
}
bool VerifySquenceOfBST(vector<int> sequence) {
int len=sequence.size();
if(len<=0)return false;
if(len==1)return true;
return judge(sequence,0,len-1);
}
};
这里我写的代码非常的恶心,不建议大家这么写.我照着王小明同学的又写了一遍.
class Solution {
public:
bool VerifySquenceOfBST(vector<int> sequence) {
int len=sequence.size();
if(len==0)return false;
if(len==1)return true;
int k=0;
while(k<len&&sequence[k]<sequence[len-1])k++;
for(int j=k;j<len;j++)
{
if(sequence[j]<sequence[len-1])return false;
}
bool a=true,b=true;
if(k>0)a=VerifySquenceOfBST(vector<int>(sequence.begin(),sequence.begin()+k));
if(k<len-1)b=VerifySquenceOfBST(vector<int>(sequence.begin()+k,sequence.end()-1));
return a&&b;
}
};
小明同学的代码写的真的很优雅....
之后是一个大佬提出的加入上下限优化时间复杂度的方法 我大概知道啥意思 但我并不想写 一会看看这里要不要补好了....
//这里好像要补一个代码//
(4)二叉树中和为某一值的路径
这个题我们先整一个递归的写法
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
vector<vector<int> > ans;
vector<int> tempans;
vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
if(root==NULL)return ans;
expectNumber-=root->val;
tempans.push_back(root->val);
if(root->left==NULL&&root->right==NULL&&0==expectNumber)ans.push_back(tempans);
if(root->left)
{
FindPath(root->left,expectNumber);
}
if(root->right)
{
FindPath(root->right,expectNumber);
}
tempans.pop_back();
return ans;
}
};
然后要整一个非递归的写法,思想就是深度优先遍历这颗树就好咯,可以拿一个栈来,然后有子节点就丢进去判断.....不想写了,算求
(5)二叉搜索树与双向链表
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(pRootOfTree==NULL)return NULL;
TreeNode * left=Convert(pRootOfTree->left);
TreeNode * right=Convert(pRootOfTree->right);
TreeNode * temp=left;
while(left&&left->right)
{
left=left->right;
}
pRootOfTree->left=left;
pRootOfTree->right=right;
if(right)right->left=pRootOfTree;
if(left){
left->right=pRootOfTree;
return temp;
}
return pRootOfTree;
}
};
emmm这个好像做了好几遍了.
看了一眼题解.好像有一种朴素做法是中序遍历这个搜索树 然后存起来,挨个改变左右指针就完事儿了
(6)二叉树的深度
我的理解中这个题是给下一个题作铺垫的
首先想到的一定是递归啦....
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
int TreeDepth(TreeNode* pRoot)
{
if(pRoot==NULL)return 0 ;
return max(TreeDepth(pRoot->left),TreeDepth(pRoot->right))+1;
}
};
看题解. 有人用层遍历写了球深度,有时候是这样的 把简单的问题想复杂,这样以后遇到复杂的问题就能很快的联系到简单的问题.....那么我们写一下层遍历获取深度.
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
int TreeDepth(TreeNode* pRoot)
{
if(pRoot==NULL)return 0 ;
queue<TreeNode*> que;
int len=0;
int size=1;
que.push(pRoot);
while(size!=0&&!que.empty())
{
size--;
TreeNode * temp=que.front();que.pop();
if(temp->left)que.push(temp->left);
if(temp->right)que.push(temp->right);
if(size==0)
{
len++;
size=que.size();
}
}
return len;
}
};
最近的记忆里真是有够烂的,一截简单的代码老是自己放坑...我是憨憨..如果当年没有好好学习去搞电竞,说不定....打不过别人也能做主播呢.2333
(7)平衡二叉树
这里就是判断左右的深度差距...把刚刚的获得深度的方法拿来.简简单单就过了....说起来,二叉树可不可以为空只是一个概念问题,可能要视情况而定了2333333
class Solution {
public:
int getDeep(TreeNode* pRoot)
{
if(pRoot==NULL)return 0;
return 1+max(getDeep(pRoot->left),getDeep(pRoot->right));
}
bool IsBalanced_Solution(TreeNode* pRoot) {
if(pRoot==NULL)return true;
if(abs(getDeep(pRoot->left)-getDeep(pRoot->right))<=1&&IsBalanced_Solution(pRoot->left)&&IsBalanced_Solution(pRoot->right))return true;
return false;
}
};
嗯 这里其实是可以剪枝的..但好像也没啥必要....
(8)二叉树的下一个结点
/*
struct TreeLinkNode {
int val;
struct TreeLinkNode *left;
struct TreeLinkNode *right;
struct TreeLinkNode *next;
TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {
}
};
*/
class Solution {
public:
queue<TreeLinkNode*> que;
void zhongxubianli(TreeLinkNode* pNode){
if(pNode==NULL)return;
zhongxubianli(pNode->left);
que.push(pNode);
zhongxubianli(pNode->right);
}
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
if(pNode==NULL)return pNode;
TreeLinkNode * p=pNode;
while(p->next)p=p->next;
zhongxubianli(p);
while(!que.empty())
{
TreeLinkNode * temp=que.front();que.pop();
if(temp==pNode)
{
if(!que.empty())return que.front();
return NULL;
}
}
}
};
就是简单的找到头 然后就中序遍历存到队列中,找到这个节点,访问下一个节点就行了
看题解.有大佬有空间复杂度O1的方法 就是直接找,当有右节点 下一个是右边的最左节点 当无右节点,是父亲的左节点,那就访问父亲节点就行,当是父亲的右节点.找父亲的父亲节点,直到找到作为某节点左节点的祖先 就是咯
/下次补代码/
(8)对称的二叉树
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
bool judge(TreeNode* p1,TreeNode* p2)
{
if(p1==NULL&&p2==NULL)return true;
if(!p1||!p2)return false;
if(p1->val!=p2->val)return false;
return judge(p1->left,p2->right)&&judge(p1->right,p2->left);
}
bool isSymmetrical(TreeNode* pRoot)
{
if(pRoot==NULL)return true;
if(judge(pRoot->left,pRoot->right))return true;
return false;
}
};
这里我依然打算分享一种非递归的算法,这样可以很快的提高代码能力
/下次补/
9.之字形打印二叉树
心态日常爆炸,一看到这个就能想起字节的HR的无奈...很对不起他,字节的面试真的做的很好,不管是回馈的速度,面试通知什么什么,还有面试的时候hr的态度都给人一种,我们是在交流的感觉,这里我想diss某企 hr面试=怼人,纯粹像是我抢你饭碗一样.....
这里先给出我后来自己做的第一版的代码,用了两个栈来避免考虑偶数层逆序输出的问题.非常滴银鑫 黑好用
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
vector<vector<int> > Print(TreeNode* pRoot) {
vector<vector<int> > ans;
if(pRoot==NULL)return ans;
stack<TreeNode*> sta1;
stack<TreeNode*> sta2;
sta1.push(pRoot);
int x=0;
int index=0;
while(!sta1.empty()||!sta2.empty())
{vector<int> tempvec;
index=0;
if(!sta1.empty())
{
while(!sta1.empty())
{
TreeNode* temp=sta1.top();
tempvec.push_back(temp->val);
if(temp->left)
sta2.push(temp->left);
if(temp->right)
sta2.push(temp->right);
sta1.pop();
}
}
else
{
while(!sta2.empty())
{
TreeNode* temp=sta2.top();
tempvec.push_back(temp->val);
if(temp->right)
sta1.push(temp->right);
if(temp->left)
sta1.push(temp->left);
sta2.pop();
}
}
if(!tempvec.empty())
{
ans.push_back(tempvec);
tempvec.clear();
}
x++;
}
return ans;
}
};
然后我们这里做一种稍微普遍一点的做法,用一个变量标识当前层应该如何放入结果中就可以咯
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
vector<vector<int> > Print(TreeNode* pRoot) {
vector<vector<int> > ans;
vector<int> tempans;
vector<int> temptempans;
if(pRoot==NULL)return ans;
queue<TreeNode *>que;
int label=0;
int size=1;
que.push(pRoot);
while(!que.empty()&&size)
{
temptempans.clear();
while(size--)
{
TreeNode * temp=que.front();que.pop();
if(temp->left)que.push(temp->left);
if(temp->right)que.push(temp->right);
temptempans.push_back(temp->val);
}
if(label==0){ans.push_back(temptempans);}
if(label==1){
tempans.clear();
for(int i=0;i<temptempans.size();i++)tempans.insert(tempans.begin(),temptempans[i]);
ans.push_back(tempans);
}
label^=1;
size=que.size();
}
return ans;
}
};
这里我依旧写的非常的愚蠢 不知道为什么看起来特别的不清晰,让我们康康题解.发现题解的老哥用了双端队列,避免了我们想啥子一样把一个中间答案转来转去.
(10)把二叉树打印成多行
....我猜这俩题顺序整反了,我人傻了.反正多写总是没错的...让我们再写一遍好了.....
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
vector<vector<int> > Print(TreeNode* pRoot) {
vector<vector<int> >ans;
vector<int> tempans;
if(pRoot==NULL)return ans;
queue<TreeNode *> que;
que.push(pRoot);
int size=1;
while(!que.empty())
{
tempans.clear();
while(size--)
{
TreeNode * top=que.front();que.pop();
if(top->left)que.push(top->left);
if(top->right)que.push(top->right);
tempans.push_back(top->val);
}
ans.push_back(tempans);
size=que.size();
}
return ans;
}
};
(11) 序列化二叉树
序列化应该大家都听过,也知道是什么意思,但是第一次写还是有点迷茫,因为要返回一个char类型的指针感觉会很麻烦......然后就 嫖题解就完事儿了0.0
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
vector<int> buf;
void dfs(TreeNode * p)
{
if(p==NULL){buf.push_back(0x7fffffff);return;}
buf.push_back(p->val);
dfs(p->left);
dfs(p->right);
}
TreeNode* dfs2(int *&p)
{
if(*p==0x7fffffff){p++;return NULL;}
TreeNode* node=new TreeNode(*p);
++p;
node->left=dfs2(p);
node->right=dfs2(p);
return node;
}
char* Serialize(TreeNode *root) {
buf.clear();
dfs(root);
int * res=new int[buf.size()];
for(int i=0;i<buf.size();i++)res[i]=buf[i];
return (char *)res;
}
TreeNode* Deserialize(char *str) {
int * p=(int *)str;
return dfs2(p);
}
};