当前位置:   article > 正文

代码随想录第21天 | 二叉搜索树的最小绝对差、二叉搜索树中的众数 、二叉树的最近公共祖先

代码随想录第21天 | 二叉搜索树的最小绝对差、二叉搜索树中的众数 、二叉树的最近公共祖先

一、前言

参考文献代码随想录

今天还是二叉树,刷的是新知识,主要涉及到二叉树的双指针遍历操作。话不多说,直接开始吧!

二、二叉搜索树的最小绝对差

1、思路一:

最原始的思路就是中序遍历搜索二叉树,出来的自然就是一个由小到大的数组,只要比较两个数组之间的值,找出最小的绝对值即可。(此方法会造成O(n)的空间复杂度)

2、代码一:

  1. class Solution {
  2. private:
  3. vector<int> res;
  4. void getMinAbs(TreeNode* root) {
  5. // 中序遍历出来就是一个升序数组
  6. if (root == NULL) return;
  7. getMinAbs(root->left);
  8. res.push_back(root->val);
  9. getMinAbs(root->right);
  10. }
  11. public:
  12. int getMinimumDifference(TreeNode* root) {
  13. int minAbs = INT_MAX;
  14. getMinAbs(root);
  15. // 只要敝比较两个相邻的元素,就可以找到
  16. for (int i = 0; i < res.size() - 1; i++) {
  17. if ((res[i + 1] - res[i]) < minAbs) {
  18. minAbs = (res[i + 1] - res[i]);
  19. }
  20. }
  21. return minAbs;
  22. }
  23. };

3、思路二:

这个思路很巧妙,利用的是二叉树上的双指针,来达到此效果。

(1)一个pre指针一个cur指针,pre指针一直指向cur的前一个节点,这实现起来在代码中很巧妙。

(2)一直遍历,一直比较就ok了。

4、代码二:

  1. class Solution {
  2. private:
  3. int result = INT_MAX;
  4. TreeNode* pre;
  5. void getMinAbs(TreeNode* cur) {
  6. if (cur == NULL) return;
  7. getMinAbs(cur->left);
  8. if (pre != NULL) {
  9. result = min(result, abs(cur->val - pre->val));
  10. }
  11. pre = cur;
  12. getMinAbs(cur->right);
  13. }
  14. public:
  15. int getMinimumDifference(TreeNode* root) {
  16. getMinAbs(root);
  17. return result;
  18. }
  19. };

三、二叉搜索树中的众数

1、思路:

我的第一思路就是递归-统计,找出最大的数,就结束了。

代码如下:

  1. class Solution {
  2. private:
  3. map<int, int> my_map;
  4. void getMap(TreeNode* root) {
  5. if (root == NULL) return;
  6. getMap(root->left);
  7. my_map[root->val]++;
  8. getMap(root->right);
  9. }
  10. public:
  11. vector<int> findMode(TreeNode* root) {
  12. int max = INT_MIN;
  13. getMap(root);
  14. for (auto it = my_map.begin(); it != my_map.end(); it++) {
  15. if (max < it->second) max = it->second;
  16. }
  17. vector<int> result;
  18. for (auto it = my_map.begin(); it != my_map.end(); it++) {
  19. if (max == it->second) result.push_back(it->first);
  20. }
  21. return result;
  22. }
  23. };

思路二的操作很华丽,也很实用,主要是利用双指针不断维护最大值和统计数以及返回的数组。

总结了以下节点:

(1)创建一个统计和最大的数值,全局变量

(2)利用中序遍历,在中的时候做和第一题差不多的逻辑,并且多加一些功能。

(3)遍历完就可以返回数组了。

2、代码如下:

  1. class Solution {
  2. private:
  3. int count = 0;
  4. int maxcount = 0;
  5. vector<int> result;
  6. TreeNode* pre;
  7. void getResult(TreeNode* cur) {
  8. if (cur == NULL) return;
  9. getResult(cur->left); // 左
  10. // 中
  11. if (pre == NULL) {
  12. count = 1;
  13. } else if (pre->val == cur->val) { // 相等就添加累加值
  14. count++;
  15. } else { // 不相等就刷新
  16. count = 1;
  17. }
  18. pre = cur;
  19. if (count == maxcount) {
  20. result.push_back(cur->val);
  21. }
  22. if (count > maxcount) { // 累加大于max,就刷新result
  23. maxcount = count;
  24. result.clear();
  25. result.push_back(cur->val);
  26. }
  27. // 右
  28. getResult(cur->right);
  29. }
  30. public:
  31. vector<int> findMode(TreeNode* root) {
  32. getResult(root);
  33. return result;
  34. }
  35. };

四、二叉树最近的公共祖先

1、思路:

这个题目首先得了解什么最近公共祖先:

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

举个例子

如果pq使6,5那么7就是公共祖先。

代码的逻辑就是:

后序遍历,左边遍历出p的话就往上返回,一直返回到根节点,返回结果。

比如遍历到10了左为空,有不为空,那就返回右边。

还有一个小的细节,例如p为7,q为5,那么7就是最近祖先,为什么呢?一旦遍历到7,就往上返回了,那么q怎么办?其实这个时候已经知道了q要么在下面,要么在右边,如果是在右边的话,那就是逻辑1了。

2、代码如下,好好体会:

  1. class Solution {
  2. private:
  3. TreeNode* findPQ(TreeNode* root, TreeNode* p, TreeNode* q) {
  4. if (root == NULL) return NULL;
  5. if (root == p || root == q) return root;
  6. // 左
  7. TreeNode* left = findPQ(root->left, p, q);
  8. // 右
  9. TreeNode* right = findPQ(root->right, p, q);
  10. // 中
  11. if (left != NULL && right != NULL) return root;
  12. else if (left != NULL && right == NULL) return left;
  13. else if (left == NULL && right != NULL) return right;
  14. else return NULL;
  15. }
  16. public:
  17. TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
  18. return findPQ(root, p, q);
  19. }
  20. };

 学习时间:2小时

leave message:

He who draws noble delights from sentimets of portry is a true poet, though he never written a line in all his life.

从诗歌情感中汲取高尚快乐的人是真正的诗人,虽然他从未写过诗。

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/882502
推荐阅读
相关标签
  

闽ICP备14008679号