class Solution {
public:
void _tree2str(TreeNode*root, string &s)
{
if(root == nullptr)
return;
s += to_string(root->val);
if(root->left != nullptr || root->right != nullptr)
{
s += '(';
_tree2str(root->left,s);
s += ')';
}
if (root->right != nullptr)
{
s+='(';
_tree2str(root->right,s);
s+=')';
}
}
string tree2str(TreeNode* root) {
string s;
_tree2str(root,s);
return s;
}
};
class Solution {
public:
vector> levelOrderBottom(TreeNode* root) {
vector> vv;
if(root == nullptr)
return vv;
queue q;
q.push(root);
while(!q.empty())
{
int sz = q.size(); //记录每次队列大小
vector v;
while(sz--)
{
TreeNode* tmp = q.front();
q.pop();
v.push_back(tmp->val);
if(tmp->left)
q.push(tmp->left);
if(tmp->right)
q.push(tmp->right);
}
vv.push_back(v);
v.clear();
}
return vv;
}
};
class Solution {
public:
vector> levelOrder(TreeNode* root) {
vector> vv;
if(root == nullptr)
return vv;
vector v1,v2;
v1.push_back(root);
while(!v1.empty() || !v2.empty())
{
for(size_t i = 0; i< v1.size(); ++i)
{
if(v1[i]->left)
v2.push_back(v1[i]->left);
if(v1[i]->right)
v2.push_back(v1[i]->right);
}
vector tmp;
for(size_t i = 0 ; i< v1.size(); ++i)
{
tmp.push_back(v1[i]->val);
}
vv.push_back(tmp);
swap(v1,v2);
v2.clear();
}
return vv;
}
};
class Solution {
public:
bool find(TreeNode* root,TreeNode* x) //查找节点
{
if(root == nullptr)
return false;
if(root == x)
return true;
return find(root->left,x) || find(root->right,x);
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)
{
if(root == nullptr)
return nullptr;
if(root == p || root == q) //如果root == p 或者 root == q就是祖先
return root;
bool isPleft,isPright,isQleft,isQright; //判断p,q是在左子树还是右子树
isPleft = find(root->left,p);
isPright = !isPleft;
isQleft = find(root->left,q);
isQright = !isQleft;
if((isPleft && isQright) || (isPright && isQleft)) //一左一右该节点就是祖先
return root;
else if(isPleft && isQleft) //都在左,递归左子树
return lowestCommonAncestor(root->left,p,q);
else if(isPright && isQright) //都在有,递归右子树
return lowestCommonAncestor(root->right,p,q);
else
return nullptr;
}
};
class Solution {
public:
bool GetPath(TreeNode* root, TreeNode* x,stack& st)
{
if(root == nullptr)
return false;
st.push(root);
if(root == x)
return true;
if(GetPath(root->left,x,st))
return true;
if(GetPath(root->right,x,st))
return true;
st.pop();
return false;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
stack pPath,qPath;
GetPath(root,p,pPath);
GetPath(root,q,qPath);
while(pPath.size() != qPath.size())
{
if(pPath.size() >qPath.size())
{
pPath.pop();
}
else
{
qPath.pop();
}
}
while(pPath.top() != qPath.top())
{
pPath.pop();
qPath.pop();
}
return qPath.top();
}
};
class Solution {
public:
void _Convert(TreeNode* root,TreeNode*& head,TreeNode*& pre)
{
if(root == nullptr)
return;
_Convert(root->left,head,pre);
//链接
if(head == nullptr)
{
pre = root;
head = root;
}
else
{
pre->right = root;
root->left = pre;
pre = root;
}
_Convert(root->right,head,pre);
}
TreeNode* Convert(TreeNode* pRootOfTree) {
TreeNode* head = nullptr, *pre = nullptr;
_Convert(pRootOfTree,head,pre);
return head;
}
};
class Solution {
public:
TreeNode* _buildTree(vector& preorder, vector& inorder,int &prei,int ibegin,int iend)
{
if(ibegin > iend) //如果开始区间位置大于结束区间,说明没有这个区间
return nullptr;
TreeNode* root = new TreeNode(preorder[prei]); //一上来先确定根节点
int rooti = ibegin;
while(rooti <= iend) //找到根节点在中序遍历的位置,确定区间
{
if(preorder[prei] == inorder[rooti])
break;
else
++rooti;
}
++prei;
//[ibegin,rooti-1][rooti][rooti+ 1,iend]
root->left = _buildTree(preorder,inorder,prei,ibegin,rooti -1);
root->right = _buildTree(preorder,inorder,prei,rooti + 1,iend);
return root;
}
TreeNode* buildTree(vector& preorder, vector& inorder) {
int prei = 0;
return _buildTree(preorder,inorder,prei,0,inorder.size() -1);
}
};
106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode) (leetcode-cn.com)
class Solution {
public:
TreeNode* _buildTree(vector& postorder, vector& inorder,int &prei,int ibegin,int iend)
{
if(ibegin > iend)
return nullptr;
TreeNode* root = new TreeNode(postorder[prei]);
int rooti = ibegin;
while(rooti <= iend)
{
if(postorder[prei] == inorder[rooti])
break;
else
++rooti;
}
--prei;
root->right = _buildTree(postorder,inorder,prei,rooti + 1,iend);
root->left = _buildTree(postorder,inorder,prei,ibegin,rooti -1);
return root;
}
TreeNode* buildTree(vector& inorder, vector& postorder) {
int prei = postorder.size() -1;
return _buildTree(postorder,inorder,prei,0,inorder.size() -1);
}
};
144. 二叉树的前序遍历 - 力扣(LeetCode) (leetcode-cn.com)
class Solution { public: vector
preorderTraversal(TreeNode* root) { //解法1:遍历所有左子树,弹栈,遍历右子树。//子问题 时间复杂度为O(N) 空间复杂度为O(N) /* vector v; stack st; auto cur = root; while(cur != nullptr || !st.empty()) { while(cur!= nullptr) // 入所有的左节点到栈 { st.push(cur); v.push_back(cur->val); //每次入的时候打印 cur = cur->left; } auto top = st.top(); //走到这说明左节点全部入栈,在让最后的左节点的右孩子入栈,重复 st.pop(); cur = top->right; //精华 } return v; */ //解法2:morris神级遍历,时间复杂度为O(N),空间复杂度为O(1) vector v; TreeNode* cur = root; TreeNode* MostRigth = nullptr; while(cur != nullptr) { MostRigth = cur->left; if(MostRigth != nullptr) { while(MostRigth->right != nullptr && MostRigth->right != cur) { MostRigth = MostRigth->right; } if(MostRigth->right == nullptr) { v.push_back(cur->val); MostRigth->right = cur; cur = cur ->left; continue; //精华 } else { MostRigth->right = nullptr; } } else{ v.push_back(cur->val); } cur = cur->right; } return v; } };
二叉树的中序遍历 - 力扣(LeetCode) (leetcode-cn.com)
class Solution {
public:
vector inorderTraversal(TreeNode* root) {
//解法1:让左节点入栈,在让右节点入栈
/* vector v;
stack st;
auto cur = root;
while(cur != nullptr || !st.empty())
{
while(cur != nullptr)
{
st.push(cur);
cur = cur->left;
}
TreeNode* top = st.top();
st.pop();
v.push_back(top->val);
cur = top->right;
}
return v;
*/
//解法二:morris遍历
vector v;
TreeNode* cur = root;
TreeNode* MostRight = nullptr;
while(cur != nullptr)
{
MostRight = cur ->left;
if(MostRight != nullptr)
{
while(MostRight->right != nullptr && MostRight->right != cur)
{
MostRight = MostRight->right;
}
if(MostRight->right == nullptr)
{
MostRight->right = cur;
cur = cur->left;
continue;
}
else
{
MostRight->right = nullptr;
}
}
v.push_back(cur->val);
cur = cur ->right;
}
return v;
}
};
145. 二叉树的后序遍历 - 力扣(LeetCode) (leetcode-cn.com)
class Solution {
public:
void AddMostRight(vector &v,TreeNode* root)
{
vectortmp;
while(root != nullptr)
{
tmp.push_back(root->val);
root = root->right;
}
reverse(tmp.begin(),tmp.end());
for(size_t i = 0; i < tmp.size();++i)
{
v.push_back(tmp[i]);
}
}
vector postorderTraversal(TreeNode* root)
{
//解法1:让左节点入栈
/*
vector v;
stack st;
auto cur = root;
TreeNode* pre = nullptr;
while( cur !=nullptr || !st.empty())
{
while(cur != nullptr)
{
st.push(cur);
cur = cur->left;
}
TreeNode* top = st.top();
if(top->right == nullptr || top->right == pre)
{
st.pop();
pre = top;
v.push_back(top->val);
}
else
{
cur = top ->right;
}
*/
//解法二:morris遍历
vector v;
TreeNode* cur = root;
TreeNode* MostRight = nullptr;
while(cur != nullptr)
{
MostRight = cur ->left;
if(MostRight != nullptr)
{
while(MostRight->right != nullptr && MostRight->right != cur)
{
MostRight = MostRight->right;
}
if(MostRight->right == nullptr)
{
MostRight->right = cur;
cur = cur->left;
continue;
}
else
{
MostRight->right = nullptr;
AddMostRight(v,cur->left);
}
}
cur = cur ->right;
}
AddMostRight(v,root);
return v;
}
};