DAY21: 二叉树530\501\236

二叉搜索树是一个有序树

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉搜索树

Leetcode: 530 二叉搜索树的最小绝对差

递归法

要掌握使用指针来记录之前的信息。

第一种解法:因为是二叉搜索树,因此中序遍历之后就会得到一个有序的数组,遍历这个数组计算就可以。

第二种方法:在递归的时候就可以直接计算得到结果了。

class Solution {
private:
    int result = INT_MAX;
    TreeNode* pre = NULL;
    void traversal(TreeNode* cur) {
        if (cur == NULL) return;
        traversal(cur->left);   // 左
        if (pre != NULL){       // 中
            result = min(result, cur->val - pre->val);//中间数值肯定比左边大
        }
        pre = cur; // 记录前一个
        traversal(cur->right);  // 右
    }
public:
    int getMinimumDifference(TreeNode* root) {
        traversal(root);
        return result;
    }
};

迭代法

class Solution {
public:
    int getMinimumDifference(TreeNode* root) {
        stack<TreeNode*> st;
        TreeNode* cur = root;
        TreeNode* pre = NULL;
        int result = INT_MAX;
        while (cur != NULL || !st.empty()) {
            if (cur != NULL) { // 指针来访问节点,访问到最底层
                st.push(cur); // 将访问的节点放进栈
                cur = cur->left;                // 左
            } else {
                cur = st.top();
                st.pop();
                if (pre != NULL) {              // 中
                    result = min(result, cur->val - pre->val);
                }
                pre = cur;
                cur = cur->right;               // 右
            }
        }
        return result;
    }
};

Leetcode: 501 二叉搜索树中的众数

递归法

第一种通用方法,遍历一遍树,把所有元素的频率放在对应的map上,输出最大的即可。代码为代码随想录提供:

代码随想录

class Solution {
private:

void searchBST(TreeNode* cur, unordered_map<int, int>& map) { // 前序遍历
    if (cur == NULL) return ;
    map[cur->val]++; // 统计元素频率
    searchBST(cur->left, map);
    searchBST(cur->right, map);
    return ;
}
bool static cmp (const pair<int, int>& a, const pair<int, int>& b) {
    return a.second > b.second;//进行快速排序
}

public:
    vector<int> findMode(TreeNode* root) {
        unordered_map<int, int> map; // key:元素,value:出现频率,要注意代码的写法
        vector<int> result;//记录结果的向量
        if (root == NULL) return result;
        searchBST(root, map);//记录频率
        vector<pair<int, int>> vec(map.begin(), map.end());
        sort(vec.begin(), vec.end(), cmp); // 给频率排个序
        result.push_back(vec[0].first);//找出最大值
        for (int i = 1; i < vec.size(); i++) {//如果还有最大值,就都放入结果输出
            // 取最高的放到result数组中
            if (vec[i].second == vec[0].second) result.push_back(vec[i].first);
            else break;
        }
        return result;
    }
};

由于是二叉搜索树,因此有规律可循。因为中序搜索二叉搜索树有序,因此如果数值一样的话,那肯定都是在相邻节点上,因此相邻两个元素进行比较,输出频率最高的元素就可以。还需要定义一个结果集,放置所有最大频率的结果,这个结果集要随着最大频率的更新而更新。

class Solution {
private:
    int maxcount = 0;
    int count = 0;
    TreeNode* pre = NULL;
    vector<int> result;//定义全局函数
    void searchnumber(TreeNode* node){
        if(node == NULL) return;

        searchnumber(node->left);
        if(pre == NULL) count = 1;
        else if(pre->val == node->val) count++;
        else count =1;
        pre = node;

        if (count == maxcount) { 
            result.push_back(node->val);
        }
        if (count > maxcount) { 
            maxcount = count;   
            result.clear();    
            result.push_back(node->val);
        }
        searchnumber(node->right);
        return;

    }
public:
    vector<int> findMode(TreeNode* root) {
        maxcount = 0;
        count = 0;
        pre = NULL;
        result.clear();
        searchnumber(root);
        return result;

    }
};

也可以迭代法来实现,具体流程基本一样。

Leetcode: 236 二叉树的最近公共祖先

因为是从下到上,因此很明显,这道题需要使用后序遍历的操作。

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root == NULL || root == p || root == q ) 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 right;
        else if(left != NULL && right == NULL) return left;
        else return NULL;
    }
};

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值