【算法训练 day23 二叉搜索树的最小绝对差、二叉搜索树的众数、二叉树的最近公共祖先】

本文主要是介绍【算法训练 day23 二叉搜索树的最小绝对差、二叉搜索树的众数、二叉树的最近公共祖先】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 一、二叉搜索树的最小绝对差-LeetCode 530
    • 思路
    • 实现代码
      • 递归处理
      • 使用数组
    • 个人问题
  • 二、二叉搜索树的众数-LeetCode 501
    • 思路
    • 实现代码
      • map统计计数
      • 递归过程中计数
    • 个人问题
  • 三.二叉树的最近公共祖先-LeeCode 236
    • 思路
    • 实现代码
    • 个人问题
    • 总结


一、二叉搜索树的最小绝对差-LeetCode 530

Leecode链接: leetcode 977
文章链接: 代码随想录
视频链接: B站

给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。

示例:

输入:root = [4,2,6,1,3]
输出:1

思路

解法1:转化为数组,然后逐个计算差值,返回最小差值即可。解法2:由于题目是搜索树,所以差值最小必定出现在相邻节点,使用全局变量保存上一个节点,中间节点计算差值并保存可能的最小差值。

实现代码

递归处理

//cpp
class Solution {
public:TreeNode* pre = nullptr;int minnum = INT32_MAX;void test(TreeNode* root){if(root == nullptr) return;test(root->left);if(pre != nullptr){minnum = min(minnum,root->val - pre->val);}pre = root;test(root->right);}int getMinimumDifference(TreeNode* root) {test(root);return minnum;}
};

使用数组

//cpp
class Solution {
private:
vector<int> vec;
void traversal(TreeNode* root) {if (root == NULL) return;traversal(root->left);vec.push_back(root->val); // 将二叉搜索树转换为有序数组traversal(root->right);
}
public:int getMinimumDifference(TreeNode* root) {vec.clear();traversal(root);if (vec.size() < 2) return 0;int result = INT_MAX;for (int i = 1; i < vec.size(); i++) { // 统计有序数组的最小差值result = min(result, vec[i] - vec[i-1]);}return result;}
};

个人问题

对于使用双指针还不够熟练。


二、二叉搜索树的众数-LeetCode 501

Leecode链接: LeetCode 501
文章链接: 代码随想录
视频链接: B站

给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。

如果树中有不止一个众数,可以按 任意顺序 返回。

示例:

输入:root = [1,null,2,2]
输出:[2]

思路

两种解法:1.中序遍历形成map数组,然后对数组进行排序,可得众数。2.递归过程中计算众数,使用一个计数器,每遇到相同的值count加1,遇到不同的值count恢复为1,然后使用maxcount记录可能成为众数出现的频率。遍历完整个树为止。

实现代码

map统计计数

//cpp
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;}
};

递归过程中计数

//cpp
class Solution {
public:int count = 0;int maxcount = 0;vector<int> res;TreeNode* pre = nullptr;void test(TreeNode* root){if(root == nullptr){return;}test(root->left);if(pre == nullptr){count = 1;}else if(root->val == pre->val){count++;}else{count = 1;}if(count>maxcount){maxcount = count;res.clear();res.push_back(root->val);}else if(count == maxcount){res.push_back(root->val);}pre = root;test(root->right);return;}vector<int> findMode(TreeNode* root) {res.clear();test(root);return res;}
};

个人问题

在实现代码时,maxcount的更新位置写在了root->val != pre->val的条件分支中,导致没有存储真正的众数;count初始值最初个人设置为1,但在执行时出现访问未定义行为,原因在于count初始值手动设置为1,但pre初始值也为1,导致不能访问正确的第一个元素的值。


三.二叉树的最近公共祖先-LeeCode 236

Leecode链接: LeetCode 236
文章链接: 代码随想录
视频链接: B站

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

示例:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3

思路

使用后序遍历,考虑一个一般情况,两个节点为某个父节点的左右子树,如果找到了该节点左右子树的递归函数就返回该节点的指针给父节点的这一层函数,这一层根据返回结果返回对应指针,如果都存在,表明要找的节点就在该父节点的孩子节点中,返回父节点自身即可。考虑一个特殊情况,如果两个节点互为父子节点,这时直接返回最先遇到的节点指针即可,如果一侧为空返回另一侧不为空的节点指针。

实现代码

//cpp
class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if(root == NULL) return NULL;if(root->val==p->val||root->val==q->val)return root;TreeNode* left_p = lowestCommonAncestor(root->left,p,q);TreeNode* right_p = lowestCommonAncestor(root->right,p,q);if(left_p&&right_p)return root;else if(!left_p&&right_p) return right_p;else if(left_p&&!right_p) return left_p;else return NULL;}
};

个人问题

代码没有自己写出来。

总结

本题比较巧妙,对各个情况处理比较特殊。

这篇关于【算法训练 day23 二叉搜索树的最小绝对差、二叉搜索树的众数、二叉树的最近公共祖先】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/975676

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

hdu1240、hdu1253(三维搜索题)

1、从后往前输入,(x,y,z); 2、从下往上输入,(y , z, x); 3、从左往右输入,(z,x,y); hdu1240代码如下: #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#inc

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

poj1330(LCA最近公共祖先)

题意:求最近公共祖先 思路:之前学习了树链剖分,然后我就用树链剖分的一小部分知识就可以解这个题目了,记录每个结点的fa和depth。然后查找时,每次将depth大的结点往上走直到x = y。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring>

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n