530.二叉搜索树的最小绝对差
递归法:这题和98.验证二叉树思路一样,只需要把中的处理改成比较相减值
代码:
int minresult = INT_MAX;//记录最小结果
TreeNode* pre = nullptr;
void traversal(TreeNode* cur){
//左
if(cur->left) traversal(cur->left);
//中,两节点相减比较
if(pre!=nullptr){
minresult = min(minresult,cur->val - pre->val);
}
pre = cur;
//右
if(cur->right) traversal(cur->right);
}
int getMinimumDifference(TreeNode* root) {
traversal(root);
return minresult;
}
501.二叉搜索树中的众数
思路:二叉搜索树的中序遍历是递增序列,利用其特性和双指针法遍历;
在中的处理上分两步,
第一步,统计相同元素的出现频率:pre指向前节点,cur指当前节点,判断两节点是否相等,等待count++,不相等说明现在遍历的元素是第一次出现与上一个节点不同的元素,所以直接把count置1.
第二步:更新结果集:核心是count统计的数比maxcount还大就加入结果集.但是还需要考虑到出现频率相等的元素。所以可以当count==maxcount就加入结果集,但是当count统计的频率比maxcount大时,说明已经出现了比原先最大频率的元素还多的次数,所以之前的结果集作废(直接清除),重新加入新的结果。
代码:
int count = 0;//统计相同元素的频率
int MaxCount = 0;//记录最大频率
vector<int> result;//结果集
TreeNode* pre = nullptr;//指向前一个节点
void searchBST(TreeNode* cur){
//左
if(cur->left) searchBST(cur->left);
//中,统计相同元素次数;更新结果集
if(pre == nullptr){//遍历到第一个元素
count = 1;
}else if(cur->val == pre->val){
count++;
}else{//排除以上遍历到第一个元素和两元素相等的情况,下面是两元素不相等,则重新把新元素出现频率置1
count = 1;
}
pre = cur;//更新节点
//更新结果集
if(count == MaxCount){//当元素的出现频率和最大的出现频率一样,证明该数有可能也是众数
result.push_back(cur->val);
}else if(count > MaxCount){//如果当前元素出现频率比最大频率大了,证明之前的结果集全作废了,因为出现了比最大频率还大的元素
MaxCount = count;
result.clear();
result.push_back(cur->val);
}
//右
if(cur->right) searchBST(cur->right);
return;
}
vector<int> findMode(TreeNode* root) {
if(root != nullptr) searchBST(root);
return result;
}
236.二叉树的最近公共祖先
思路:需要找两节点的上层公共节点,肯定是先确定pq的位置再回上层处理中间节点,所以一定是从下往上遍历,用后序遍历,左右中。
在中间的处理需要分两种情况:
情况1:pq出现在在公共节点的两侧,返回其最近的节点一层层往上返回
情况2:加入q是p的父节点,题目要求这种情况q也是pq的公共祖先。这种当遍历到q就会直接返回q节点给上层,不需要再往下遍历。因为如果p出现在q节点的子树下,也是返回q节点,如果p出现在其q的右侧(作为兄弟节点)那么就会回到情况1,所以左子树也是返回q节点,所以无论pq位置如何都直接返回q节点。
代码:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == NULL) return NULL;
if(root==p || root==q) return root;
//左右,记录该节点左右子树是否有出现pq,如果有left或right是有值的,否则就是null
TreeNode* left = lowestCommonAncestor(root->left,p,q);
TreeNode* right = lowestCommonAncestor(root->right,p,q);
//中,判断左右子树返回值有没有出现pq
if(left!=NULL && right!=NULL) return root;
else if(left!=NULL && right==NULL) return left;
else if(left==NULL && right!=NULL) return right;
else return NULL;
}