【算法训练 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

相关文章

公共筛选组件(二次封装antd)支持代码提示

如果项目是基于antd组件库为基础搭建,可使用此公共筛选组件 使用到的库 npm i antdnpm i lodash-esnpm i @types/lodash-es -D /components/CommonSearch index.tsx import React from 'react';import { Button, Card, Form } from 'antd'

代码随想录算法训练营:12/60

非科班学习算法day12 | LeetCode150:逆波兰表达式 ,Leetcode239: 滑动窗口最大值  目录 介绍 一、基础概念补充: 1.c++字符串转为数字 1. std::stoi, std::stol, std::stoll, std::stoul, std::stoull(最常用) 2. std::stringstream 3. std::atoi, std

人工智能机器学习算法总结神经网络算法(前向及反向传播)

1.定义,意义和优缺点 定义: 神经网络算法是一种模仿人类大脑神经元之间连接方式的机器学习算法。通过多层神经元的组合和激活函数的非线性转换,神经网络能够学习数据的特征和模式,实现对复杂数据的建模和预测。(我们可以借助人类的神经元模型来更好的帮助我们理解该算法的本质,不过这里需要说明的是,虽然名字是神经网络,并且结构等等也是借鉴了神经网络,但其原型以及算法本质上还和生物层面的神经网络运行原理存在

YOLO v3 训练速度慢的问题

一天一夜出了两个模型,仅仅迭代了200次   原因:编译之前没有将Makefile 文件里的GPU设置为1,编译的是CPU版本,必须训练慢   解决方案: make clean  vim Makefile make   再次训练 速度快了,5分钟迭代了500次

大林 PID 算法

Dahlin PID算法是一种用于控制和调节系统的比例积分延迟算法。以下是一个简单的C语言实现示例: #include <stdio.h>// DALIN PID 结构体定义typedef struct {float SetPoint; // 设定点float Proportion; // 比例float Integral; // 积分float Derivative; // 微分flo

LeetCode--155 最小栈

题目 设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。push(x) -- 将元素 x 推入栈中。pop() -- 删除栈顶的元素。top() -- 获取栈顶元素。getMin() -- 检索栈中的最小元素。 示例 MinStack minStack = new MinStack();minStack.push(-2);minStack.push

将一维机械振动信号构造为训练集和测试集(Python)

从如下链接中下载轴承数据集。 https://www.sciencedirect.com/science/article/pii/S2352340918314124 import numpy as npimport scipy.io as sioimport matplotlib.pyplot as pltimport statistics as statsimport pandas

剑指offer(C++)--平衡二叉树

题目 输入一棵二叉树,判断该二叉树是否是平衡二叉树。 class Solution {public:bool IsBalanced_Solution(TreeNode* pRoot) {if(pRoot==NULL)return true;int left_depth = getdepth(pRoot->left);int right_depth = getdepth(pRoot->rig

剑指offer(C++)--两个链表的第一个公共结点

题目 输入两个链表,找出它们的第一个公共结点。 解法一 两个链表一定有交点的话,方法是指向短链表指针先走完,然后指向长链表,指向长链表指针后走完,指向短链表。所以,第二次走过,一定会在交点相遇。 class Solution {public:ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) {ListN

二叉树三种遍历方式及其实现

一、基本概念 每个结点最多有两棵子树,左子树和右子树,次序不可以颠倒。 性质: 1、非空二叉树的第n层上至多有2^(n-1)个元素。 2、深度为h的二叉树至多有2^h-1个结点。 3、对任何一棵二叉树T,如果其终端结点数(即叶子结点数)为n0,度为2的结点数为n2,则n0 = n2 + 1。 满二叉树:所有终端都在同一层次,且非终端结点的度数为2。 在满二叉树中若其深度为h,则其所包含