c++中如何实现单调栈_c++单调栈实现方法

单调是保持元素单调递增或递减的栈结构,用于解决下一更大/更小元素等问题。1. 分为单调递增栈和单调递减栈,通过在入栈前弹出破坏顺序的元素维护单调性。2. 使用std::stack实现时通常存储数组下标,便于访问原数组和计算距离。3. 在寻找每个元素右侧第一个更小元素时采用单调递减栈,通过while循环持续弹出大于等于当前元素的栈顶元素。4. 寻找下一个更大元素则使用单调递增栈,调整比较条件为大于关系即可。5. 每个元素最多入栈出栈一次,时间复杂度为O(n)。核心在于理解单调性维护机制并应用于最近更大或更小元素问题。

c++中如何实现单调栈_c++单调栈实现方法

单调栈是一种特殊的栈结构,其内部元素始终保持单调递增或单调递减的顺序。它常用于解决“下一个更大元素”、“最大矩形面积”等一类问题。在C++中,我们可以借助std::stack来高效实现单调栈。

什么是单调栈

单调栈分为两种:

单调递增栈:从栈底到栈顶元素值递增(允许相等为非严格递增) 单调递减栈:从栈底到栈顶元素值递减(允许相等为非严格递减)

维护单调性的关键是在入栈前,将破坏顺序的元素从栈顶弹出。

使用 std::stack 实现单调递减栈

下面以单调递减栈为例,实现在数组中找到每个元素右边第一个更小的元素(Next Smaller Element)。

立即学习“C++免费学习笔记(深入)”;

#include iostream>
#include
#include

std::vector nextSmallerElement(const std::vector& arr) {
    int n = arr.size();
    std::vector result(n, -1); // 默认值为-1,表示右侧无更小元素
    std::stack stk; // 存储的是索引

    for (int i = 0; i         // 维护单调递减:当前元素小于栈顶对应值时,更新结果
        while (!stk.empty() && arr[i]             result[stk.top()] = arr[i];
            stk.pop();
        }
        stk.push(i);
    }

    return result;
}

int main() {
    std::vector arr = {4, 2, 6, 1, 3};
    std::vector res = nextSmallerElement(arr);

    for (int val : res) {
        std::cout     }
    // 输出: 2 1 1 -1 -1
    return 0;
}

实现单调递增栈(找下一个更大元素)

只需调整比较方向即可实现单调递增栈,用于找每个元素右边第一个更大的元素。

std::vector nextGreaterElement(const std::vector& arr) {
    int n = arr.size();
    std::vector result(n, -1);
    std::stack stk;

    for (int i = 0; i         // 当前元素大于栈顶元素时,更新结果
        while (!stk.empty() && arr[i] > arr[stk.top()]) {
            result[stk.top()] = arr[i];
            stk.pop();
        }
        stk.push(i);
    }

    return result;
}

关键点总结

使用单调栈时需注意以下几点:

栈中通常存储数组下标而非元素值,便于访问原数组和计算距离 循环中通过 while 而不是 if 来持续弹出破坏单调性的元素 根据题目需求选择递增或递减栈 时间复杂度为 O(n),因为每个元素最多入栈出栈一次

基本上就这些。掌握单调栈的核心在于理解其单调性维护机制,并灵活应用于各类“最近更大/更小元素”的场景。不复杂但容易忽略细节。

以上就是c++++中如何实现单调栈_c++单调栈实现方法的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1477883.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月19日 02:25:36
下一篇 2025年12月19日 02:25:44

相关推荐

  • c++怎么使用命名管道进行通信_c++命名管道通信方法

    命名管道在Windows和Linux中均支持进程间通信。1. Windows使用CreateNamedPipe创建,客户端通过CreateFile连接,读写用ReadFile/WriteFile;2. Linux通过mkfifo创建FIFO文件,以open、read、write进行通信;3. 两端需…

    2025年12月19日
    000
  • c++怎么获取命令行参数_C++ main函数获取命令行参数详解

    C++中main函数通过int main(int argc, char* argv[])接收命令行参数,argc为参数数量,argv为参数数组,程序名占argv[0],实际参数从argv[1]开始,使用时需确保不越界。 在C++中,main函数可以通过特定的参数形式来接收命令行输入的参数。这在编写需…

    2025年12月19日
    000
  • c++多线程编程怎么加锁_c++多线程加锁方法

    C++多线程中通过std::mutex、std::lock_guard、std::unique_lock和std::lock实现加锁,防止数据竞争。1. std::mutex提供基础lock/unlock操作,但需手动管理;2. std::lock_guard采用RAII机制,构造时加锁,析构时解锁…

    2025年12月19日
    000
  • c++中的匿名命名空间有什么用_c++匿名命名空间使用方法

    匿名命名空间用于限制符号链接性,使其仅在当前编译单元内可见。它提供内部链接性,避免命名冲突与污染,支持类和模板定义,优于旧式static用法,适用于封装文件局部的辅助功能,但不应在头文件中使用以防多份副本问题。 在C++中,匿名命名空间(anonymous namespace)的主要作用是限制变量、…

    2025年12月19日
    000
  • c++怎么实现反射_c++反射实现方法

    C++无原生反射因强调性能,仅提供有限RTTI;可通过宏注册、模板元编程、代码生成工具或第三方库(如rttr)实现类似功能,常用于序列化、动态创建对象等场景。 在C++中,语言本身不支持像Java或C#那样的原生反射机制。也就是说,C++没有内置能力在运行时动态获取类名、成员变量、方法名或调用函数。…

    2025年12月19日
    000
  • c++中nullptr和NULL有什么区别_c++ nullptr与NULL区别解析

    nullptr是类型安全的空指针,NULL本质为整型常量易引发歧义;2. nullptr提升代码可读性,明确表示空指针意图;3. 模板中nullptr更安全,避免类型推导错误;4. C++11及以上推荐使用nullptr替代NULL,增强安全性与现代性。 在C++中,nullptr 和 NULL 都…

    2025年12月19日
    000
  • c++怎么实现观察者模式_c++观察者模式实现方法

    观察者模式通过定义一对多依赖实现对象间松耦合通信,当被观察者状态改变时自动通知所有观察者。使用C++抽象基类定义Observer接口,Subject维护weak_ptr观察者列表并提供attach、detach和notify方法,ConcreteObserver通过shared_from_this注…

    2025年12月19日
    000
  • c++怎么操作IO多路复用select_c++ IO多路复用select方法

    C++中使用select实现IO多路复用,通过调用select()函数监控多个文件描述符的读写状态,结合fd_set宏操作管理集合,示例程序监听socket和标准输入,每次循环重置集合并调用select等待事件,支持超时机制,但存在性能瓶颈和fd数量限制,适用于小型或跨平台项目。 在C++中使用IO…

    2025年12月19日
    000
  • c++中如何在函数中使用静态变量_c++静态变量使用方法

    静态变量在函数内用static声明,程序运行期间仅初始化一次,值在函数调用间保持;普通局部变量每次调用都会重新创建和销毁。 在C++中,静态变量(static variable)可以在函数内部使用,其特点是:该变量在程序的整个运行期间只初始化一次,且它的值在多次函数调用之间保持不变。这与普通局部变量…

    2025年12月19日
    000
  • c++虚函数和纯虚函数是什么_c++ 虚函数与纯虚函数解析

    虚函数允许在基类中定义可被派生类重写的成员函数,实现运行时多态;纯虚函数则强制派生类实现特定接口,定义抽象类。1. 虚函数用virtual声明,可有默认实现,支持动态绑定;2. 纯虚函数以=0结尾,无实现,使类成为抽象类,不可实例化;3. 含虚函数的类可实例化,含纯虚函数的类必须由派生类实现才能使用…

    2025年12月19日
    000
  • c++中如何实现贪心算法选择问题_c++贪心算法选择问题实现方法

    贪心算法通过每步选择最早结束的活动来最大化不冲突活动数量,C++实现包括定义活动结构体、按结束时间排序并遍历选择兼容活动,时间复杂度O(n log n),适用于满足贪心选择性质的问题。 贪心算法在C++中解决选择问题的核心是:每一步都做出当前最优的选择,希望最终结果是全局最优。针对“选择问题”,比如…

    2025年12月19日
    000
  • c++中怎么实现单例模式_C++单例模式设计与实现

    推荐使用局部静态变量实现单例模式,C++11保证其线程安全,兼具延迟初始化、无需手动加锁、代码简洁等优点,优于懒汉式和饿汉式。 在C++中实现单例模式,核心目标是确保一个类在整个程序生命周期中只有一个实例,并提供一个全局访问点。常见的实现方式包括懒汉式、饿汉式以及结合现代C++特性的线程安全版本。 …

    2025年12月19日
    000
  • C++如何比较两个字符串是否相等_C++ 字符串比较方法

    C++中比较字符串相等的方法有:①std::string用==操作符最简洁;②compare()成员函数返回0表示相等,适合复杂场景;③C风格字符串用strcmp(),需包含,返回0为相等;④忽略大小写可自定义函数结合tolower实现。推荐优先使用std::string和==。 在C++中,比较两…

    2025年12月19日
    000
  • c++中的union联合体怎么用_c++ union联合体使用方法

    union允许在相同内存存储不同数据类型,但任一时刻仅一个成员有效;其大小由最大成员决定,用于节省内存。 在C++中,union(联合体)是一种特殊的数据类型,允许你在同一块内存位置存储不同的数据类型。但同一时间只能有一个成员有效。它的主要用途是节省内存,特别是在需要处理多种数据类型但不会同时使用的…

    2025年12月19日
    000
  • c++如何获取文件的大小和修改日期_c++ 文件大小与修改日期获取方法

    c++kquote>使用C++17 filesystem可跨平台获取文件大小和修改日期,推荐std::filesystem::file_size和last_write_time,配合chrono处理时间转换;传统stat函数适用于旧版本C++,兼容性好但需注意平台差异。 在C++中获取文件的大…

    2025年12月19日
    000
  • c++怎么使用智能指针shared_ptr_c++ shared_ptr使用方法

    c++kquote>答案:std::shared_ptr通过引用计数管理对象生命周期,需包含头文件并启用C++11及以上标准;推荐使用std::make_shared创建,支持共享所有权与引用计数追踪,调用reset()可释放资源,通过*和->访问对象,但需注意避免循环引用导致内存泄漏,…

    2025年12月19日
    000
  • c++ STL中的迭代器是什么_c++ STL迭代器使用方法

    迭代器是C++ STL中用于访问容器元素的通用机制,类似指针,支持遍历和操作元素而不暴露内部结构。每种容器提供对应迭代器类型,如vector::iterator、list::iterator等,可通过*it读取值、++it移动位置。STL定义五类迭代器:输入、输出、前向、双向和随机访问迭代器,功能依…

    2025年12月19日
    000
  • c++怎么自定义排序规则_自定义排序函数实现

    C++中自定义排序通过std::sort配合比较逻辑实现,可使用普通函数、Lambda表达式、函数对象或结构体排序。1. 普通函数示例为按绝对值升序排列整数;2. Lambda表达式推荐用于简洁定义,如对pair先按第一关键字升序再按第二关键字降序;3. 函数对象适用于复杂逻辑,如按字符串长度排序;…

    2025年12月19日
    000
  • c++怎么处理Unicode和UTF-8编码_c++ Unicode与UTF-8处理方法

    答案:C++中处理UTF-8需理解其变长编码特性,使用std::string存储,避免字节索引误用,推荐utf8cpp等库安全遍历码点,文件操作时保持编码一致,防止意外转换。 在C++中处理Unicode和UTF-8编码,关键在于理解字符串的编码方式以及如何正确读取、存储和操作多字节字符。C++标准…

    2025年12月19日
    000
  • c++中如何实现并查集的合并_c++并查集合并方法

    并查集通过find和merge操作管理集合合并与查询,使用路径压缩和按秩合并优化效率。初始化parent数组使每个节点指向自身,rank记录树高;find递归查找根并压缩路径,merge比较rank决定合并方向,避免退化为链表;二者结合使操作均摊复杂度接近O(α(n))。示例中创建5元素并查集,依次…

    2025年12月19日
    000

发表回复

登录后才能评论
关注微信