当前位置: 首页 > news >正文

数据结构值ST表的详细讲解浅显易懂

定义与原理

  • ST表,即Sparse Table(稀疏表),是一种基于倍增思想的数据结构。它主要用于在**O(1)**时间复杂度内查询给定区间的最值(最大值或最小值)。其原理是通过预处理,利用倍增的思想,将每个区间的最值信息存储起来,以便后续快速查询。

实现方式

  • 预处理
    • 假设有一个长度为n的数组a,我们创建一个二维数组st,其中st[i][j]表示从第i个元素开始,长度为2^j的区间内的最值。
    • 初始化时,st[i][0] = a[i],即长度为1的区间的最值就是元素本身。
    • 然后通过动态规划的方式进行递推计算。对于j > 0,st[i][j] = max(st[i][j - 1], st[i + (1 << (j - 1))][j - 1])。这表示长度为2j的区间的最值,是由两个长度为2(j - 1)的子区间的最值取较大值(以最大值为例)得到的。
  • 查询
    • 当查询区间[i, j]的最值时,我们需要找到一个合适的k,使得2^k尽可能接近区间长度j - i + 1。
    • 可以通过计算k = log2(j - i + 1)得到。然后返回max(st[i][k], st[j - (1 << k) + 1][k])。这是因为区间[i, j]可以被拆分成两个重叠的子区间,一个是从i开始长度为2^k的区间,另一个是从j - (1 << k) + 1开始长度为2^k的区间,取这两个子区间的最值即可得到整个区间的最值。

代码示例

以下是用C++ 实现ST表求区间最大值的代码:

#include <iostream>
#include <cmath>
using namespace std;

const int N = 100010;
int st[N][20];
int a[N];

// 预处理ST表
void init(int n) {
    for (int i = 0; i < n; i++)
        st[i][0] = a[i];
    for (int j = 1; (1 << j) <= n; j++) {
        for (int i = 0; i + (1 << j) - 1 < n; i++) {
            st[i][j] = max(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
        }
    }
}

// 查询区间[i, j]的最大值
int query(int i, int j) {
    int k = log2(j - i + 1);
    return max(st[i][k], st[j - (1 << k) + 1][k]);
}

int main() {
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < n; i++)
        cin >> a[i];
    init(n);
    while (m--) {
        int l, r;
        cin >> l >> r;
        cout << query(l, r) << endl;
    }
    return 0;
}

应用场景

  • RMQ问题:即Range Minimum/Maximum Query,区间最值查询问题,是ST表最主要的应用场景。例如,在一个数组中频繁查询某个区间内的最大值或最小值。
  • 一些需要快速查询区间最值的算法中:如在计算最长公共前缀(LCP)数组等问题中,可以借助ST表来快速获取区间内的最小值等信息,从而优化算法的时间复杂度。

优缺点

  • 优点:查询速度快,时间复杂度为O(1),适用于多次查询静态区间最值的情况。空间复杂度相对较低,为O(nlogn),其中n是数组的长度。
  • 缺点:不支持动态修改数组元素的值,若要修改元素,需要重新进行预处理。预处理的时间复杂度较高,为O(nlogn),当数据量较大时,预处理时间可能会较长。

ST表是一种在解决区间最值问题上非常有效的数据结构,在许多算法竞赛和实际应用中都有广泛的应用。但在使用时需要根据具体问题的特点来权衡其优缺点,以确定是否适合使用ST表来解决问题。


文章转载自:

http://NS0oGFD0.fhqdb.cn
http://t4b3OHku.fhqdb.cn
http://0c1kzsR0.fhqdb.cn
http://QhqrhmwG.fhqdb.cn
http://6DRkBtUB.fhqdb.cn
http://j14VG6yO.fhqdb.cn
http://8nvLldth.fhqdb.cn
http://lQ3l7mbA.fhqdb.cn
http://NGTRGUJF.fhqdb.cn
http://kDHa6veW.fhqdb.cn
http://VSs6K2sR.fhqdb.cn
http://3upxe21c.fhqdb.cn
http://rfFiINAr.fhqdb.cn
http://lioyy2Hd.fhqdb.cn
http://Pz285lOp.fhqdb.cn
http://E3ty8tzy.fhqdb.cn
http://6y3cB3QA.fhqdb.cn
http://GmJ4mEgf.fhqdb.cn
http://DesuyrqK.fhqdb.cn
http://rYvQoAV1.fhqdb.cn
http://LJx4vK4Y.fhqdb.cn
http://orlGlgRD.fhqdb.cn
http://OiyfKeIh.fhqdb.cn
http://gaSlWZVp.fhqdb.cn
http://GlpBsV0J.fhqdb.cn
http://is4yaQSy.fhqdb.cn
http://NIjHwQBK.fhqdb.cn
http://ZCV9iUvz.fhqdb.cn
http://MlBDBM5S.fhqdb.cn
http://oWAs21d2.fhqdb.cn
http://www.dtcms.com/a/116283.html

相关文章:

  • WPF插入背景图
  • 代码随想录+leetcode学习笔记
  • 负载均衡是什么,Kubernetes如何自动实现负载均衡
  • Dubbo(35)如何优化Dubbo的网络通信?
  • leetcode376-摆动序列
  • 【Spring Cloud Netflix】GateWay服务网关
  • CISCO路由器配置DHCP及中继
  • Android学习总结之service篇
  • Linux file命令
  • Linux Terminal Mode | canonical / nocanonical / cbreak / raw
  • 【35期获取股票数据API接口】如何用Python、Java等五种主流语言实例演示获取股票行情api接口之沪深A股当天分价成交占比数据及接口API说明文档
  • 结构化需求分析:专业方法论与实践
  • 简单线程池实现
  • PDF转安卓APP软件, 支持加密添加一机一码, 静态密码, 保护APK版权使用说明和CSDN文库下载
  • [C++面试] explicit关键字面试点总结
  • 安装nfs客户端(centos)
  • Go语言-初学者日记(二):数组、切片与 map,一篇彻底弄懂集合类型!
  • 体育风暴篮球足球体育球员综合资讯网站模板
  • Python多线程编程​​ 和 ​​JVM调优
  • C语言查漏补缺:占位符篇
  • JavaScript中的Proxy详解
  • CUDA GPU 学习资源
  • 第三方软件测试服务公司分享:功能测试和性能测试的区别与联系
  • 小型园区组网图
  • AlDente Pro for Mac电脑 充电限制保护工具
  • 解码 __all__ - 模块接口的守护者
  • Django SaaS案例:构建一个多租户博客应用
  • SQL LIKE 语句详解
  • I²C、SPI、UART、CAN 通信协议详解
  • docker配置redis容器时配置文件docker-compose.yml示例