代码随想录刷题随记18-二叉树7
530.二叉搜索树的最小绝对差
leetcode链接
注意是搜索二叉树所以是有序的,所以如果按照中序遍历的话,最近差异的只会存在于前后遍历的两个节点之间,而不会出现跨界的的问题。
class Solution {
public:
int getMinimumDifference(TreeNode* root) {
int difmin=INT_MAX;
stack<TreeNode * > mystack;
TreeNode * cur=root;
TreeNode * pre=nullptr;
while(cur!=nullptr||!mystack.empty()){
if(cur!=nullptr){
mystack.push(cur);
cur=cur->left;
}
else{
cur=mystack.top();
mystack.pop();
if(pre!=nullptr){
int tmp=abs(cur->val-pre->val);
if(tmp<difmin){
difmin=tmp;
}
}
pre=cur;
cur=cur->right;
}
}
return difmin;
}
};
二叉搜索树中的众数
leetcode 链接
如果不是二叉搜索树,最直观的方法一定是把这个树都遍历了,用map统计频率,把频率排个序,最后取前面高频的元素的集合。
因为二叉搜索树的中序遍历是有序的所以,相同的数字一定是挨着的,所以当统计到新的数的时候之前的数以及完全统计完了
解题代码:
class Solution {
public:
vector<int> findMode(TreeNode* root) {
TreeNode * cur=root;
TreeNode * pre=nullptr;
int cnt=0;
int cntcur=0;
stack<TreeNode *> mystack;
vector<int> ret;
while(cur!=nullptr||!mystack.empty()){
if(cur!=nullptr){
mystack.push(cur);
cur=cur->left;
}
else{
cur=mystack.top();
mystack.pop();
if(pre==nullptr)
cntcur++;
if(pre!=nullptr){
if(pre->val==cur->val){
cntcur++;
}
else{
cntcur=1;
}
}
if(cntcur>cnt){
cnt=cntcur;
//清楚很重要
ret.clear();
ret.push_back(cur->val);
}
else if(cntcur==cnt){
ret.push_back(cur->val);
}
pre=cur;
cur=cur->right;
}
}
return ret;
}
};
236. 二叉树的最近公共祖先
leetcode链接
遇到这个题目首先想的是要是能自底向上查找就好了,这样就可以找到公共祖先了。
后序遍历(左右中)就是天然的回溯过程,可以根据左右子树的返回值,来处理中节点的逻辑。
struct info{
bool findp;
bool findq;
bool iscommen;
TreeNode * commonnode;
};
class Solution {
public:
info* subtask(TreeNode* root, TreeNode* p, TreeNode* q){
info* ret=new info();
if(root==nullptr){
ret->findp=false;
ret->findq=false;
ret->iscommen=false;
ret->commonnode=nullptr;
return ret;
}
info* left=subtask(root->left, p, q);
info* right=subtask(root->right, p, q);
if(left->iscommen||right->iscommen){
ret->findp=true;
ret->findq=true;
ret->commonnode=left->iscommen?left->commonnode:right->commonnode;
ret->iscommen=true;
}
else if((left->findp&&right->findq)||(left->findq&&right->findp)){
ret->findp=true;
ret->findq=true;
ret->iscommen=true;
ret->commonnode=root;
}
else if((root==q&&left->findp)||(root==q&&right->findp)||(root==p&&left->findq)||(root==p&&right->findq)){
ret->findp=true;
ret->findq=true;
ret->iscommen=true;
ret->commonnode=root;
}
else{
ret->findp=(left->findp||right->findp||root==p);
ret->findq=left->findq||right->findq||root==q;
ret->commonnode=nullptr;
ret->iscommen=false;
}
return ret;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==nullptr)
return nullptr;
info* ret=subtask(root,p, q) ;
return ret->commonnode;
}
};