代码随想录算法训练营day21 | LeetCode 530. 二叉搜索树的最小绝对差 501. 二叉搜索树中的众数 236. 二叉树的最近公共祖先

530. 二叉搜索树的最小绝对差(题目链接:力扣

思路:因为是二叉搜索树,所以只需要额外用一个指针保存前一个指向的节点,每次遍历将本节点与前一个节点的值相减得到差值,遍历完整颗二叉搜索树,就可以得到结果。

int lastValue = -1;

int traversal(TreeNode* root, int minValue){
    if(root->left) minValue = traversal(root->left, minValue);
    if(lastValue != -1 && root->val - lastValue < minValue) minValue = root->val - lastValue;
    lastValue = root->val;
    if(root->right) minValue = traversal(root->right, minValue);
    return minValue;
}

int getMinimumDifference(TreeNode* root) {
    return traversal(root, INT_MAX);
}
int getMinimumDifference(TreeNode* root) {
    stack<TreeNode*> st;
    TreeNode* cur = root;
    int result = INT_MAX;
    int lastValue = -1;
    while(!st.empty() || cur){
        while(cur){
            st.push(cur);
            cur = cur->left;
        }
        cur = st.top();
        st.pop();
        if(lastValue != -1 && cur->val - lastValue < result) result = cur->val - lastValue;
        lastValue = cur->val;
        cur = cur->right;
    }
    return result;
}

501. 二叉搜索树中的众数(题目链接:力扣

思路:因为是二叉搜索树,所以只遍历一次即可,碰到相同节点计数,如果某次计数最大,就将前面存储好了的值全部丢掉,把本次计数最大对应的节点的值存下来(本来我是用stack存放中间结果,最后再一次性倒进vector的,后来看了卡哥解析才知道可以直接用vector,每次清空的时候直接vector.clear()就可以了)。如果不是二叉搜索树需要遍历两次,第一次遍历用map计数,第二次把计数到map中最大值对应的节点值存下来。

int maxCount = 0;
int lastCount = 0;
TreeNode* pre = NULL;
stack<int> st;
void traversal(TreeNode* root){
    if(root->left) traversal(root->left);
    if(pre && root->val == pre->val) lastCount++;
    else lastCount = 1;
    if(lastCount > maxCount){
        maxCount = lastCount;
        while(!st.empty()){
            st.pop();
        }
        st.push(root->val);
    }else if(lastCount == maxCount){
        st.push(root->val);
    }
    pre = root;
    if(root->right) traversal(root->right);
}

vector<int> findMode(TreeNode* root) {
    traversal(root);
    vector<int> vec;
    while(!st.empty()){
        vec.push_back(st.top());
        st.pop();
    }
    return vec;
}
vector<int> findMode(TreeNode* root) {
    vector<int> result;
    stack<TreeNode*> st;
    stack<int> stNums;
    int maxCount = 0;
    int lastCount = 0;
    TreeNode* cur = root;
    TreeNode* pre = NULL;
    while(!st.empty() || cur){
        while(cur){
            st.push(cur);
            cur = cur->left;
        }
        cur = st.top();
        st.pop();
        if(pre && cur->val == pre->val) lastCount++;
        else lastCount = 1;
        if(lastCount > maxCount){
            maxCount = lastCount;
            while(!stNums.empty()){
                stNums.pop();
            }
            stNums.push(cur->val);
        }else if(lastCount == maxCount){
            stNums.push(cur->val);
        }
        pre = cur;
        cur = cur->right;
    }
    while(!stNums.empty()){
        result.push_back(stNums.top());
        stNums.pop();
    }
    return result;
}

236. 二叉树的最近公共祖先(题目链接:力扣

思路:这道题想了很久(主要卡在了记录路径这里,后来深刻理解了回溯,并且这种记录中间路径的做法一定要用全局变量来存,不然回溯会导致丢失数据),先找到p,并把路径存进stack,然后从stack中依次取出节点,判断该节点下是否能找到q,找到就返回。

stack<TreeNode*> st;
bool flag = false;
void traversal1(TreeNode* root, TreeNode* p, stack<TreeNode*>& stTmp){
    if(root == p){
        stTmp.push(root);
        st = stTmp;
        flag = true;
    }
    if(!flag && root->left){
        stTmp.push(root);
        traversal1(root->left, p, stTmp);
        stTmp.pop(); 
    }
    if(!flag && root->right){
        stTmp.push(root);
        traversal1(root->right, p, stTmp);
        stTmp.pop();
    }
}

bool traversal2(TreeNode* root, TreeNode* q){
    if(root == NULL) return false;
    return root == q || traversal2(root->left, q) || traversal2(root->right, q);
}

TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    stack<TreeNode*> stTmp;
    traversal1(root, p, stTmp);
    while(!st.empty()){
        TreeNode* cur = st.top();
        if(traversal2(cur, q)) return cur;
        st.pop();
    }
    return root;
}

后来看了解析才发现真tm简单,主打一个从叶子节点回溯,找到值然后返回。

TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    if(root == NULL || root == q || root == p) return root;
    TreeNode* left = lowestCommonAncestor(root->left, p, q);
    TreeNode* right = lowestCommonAncestor(root->right, p, q);
    if(left != NULL && right != NULL) return root;
    if(left != NULL && right == NULL) return left;
    if(left == NULL && right != NULL) return right;
    return NULL;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_porter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值