C++ day58 每日温度 下一个更大元素

题目1:739 每日温度

题目链接:每日温度

对题目的理解

temperature[i]表示每天的温度,返回数组answer,answer[i]指对于第i天,下一个更高温度最近出现在几天后,如果气温在这之后都不会升高,用0来代替

暴力解法

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        vector<int> answer(temperatures.size(),0);
        for(int i=0;i<temperatures.size();i++){
            for(int j=i+1;j<temperatures.size();j++){
                if(temperatures[j]>temperatures[i]){
                    answer[i]=j-i;
                    break;
                } 
            }
        }
        return answer;
    }
};

会报超时错误

单调栈

1)何时想到使用单调栈?

通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈了,时间复杂度为O(n)

单调栈的本质是空间换时间,因为在遍历的过程中需要用一个栈来记录右边第一个比当前元素高的元素,优点是整个数组只需要遍历一次。

就是用一个栈来记录已经遍历过的元素

2)如何使用单调栈?

单调栈里只需要存放元素的下标i就可以了,如果需要使用对应的元素,直接T[i]就可以获取。

只有递增的时候,栈里要加入一个元素i的时候,才知道栈顶元素在数组中右面第一个比栈顶元素大的元素是i。

使用单调栈主要有三个判断条件。

  • 当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况
  • 当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况
  • 当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况

整个流程

定义result数组的时候,就应该直接初始化为0,如果result没有更新,说明这个元素右面没有更大的了,也就是为0。

伪代码

代码

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        vector<int> result(temperatures.size(),0);
        stack<int> st;
        st.push(0);
        for(int i=1;i<temperatures.size();i++){
            if(temperatures[i]<temperatures[st.top()]) st.push(i);
            else if(temperatures[i]==temperatures[st.top()]) st.push(i);
            else {
                while(!st.empty() && temperatures[i]>temperatures[st.top()]){
                    result[st.top()] = i-st.top();
                    st.pop();
                }
                st.push(i);
            }
        }
        return result;      
    }
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

精简代码

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        vector<int> result(temperatures.size(),0);
        stack<int> st;
        st.push(0);
        for(int i=1;i<temperatures.size();i++){
            while(!st.empty() && temperatures[i]>temperatures[st.top()]){
                result[st.top()]=i-st.top();
                st.pop();
            }
            if(temperatures[i]<=temperatures[st.top()]) st.push(i);
        }
        return result;      
    }
};

上述代码会出现如下错误

原因是for循环中下面的if判断并没有限制st,若st可能出现空栈的情况

将代码改正如下:

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        vector<int> result(temperatures.size(),0);
        stack<int> st;
        st.push(0);
        for(int i=1;i<temperatures.size();i++){
            while(!st.empty() && temperatures[i]>temperatures[st.top()]){
                result[st.top()]=i-st.top();
                st.pop();
            }
            if(!st.empty() && temperatures[i]<=temperatures[st.top()]) st.push(i);
        }
        return result;      
    }
};

这个时候倒是不报执行错误了,又有新的错误产生了,案例错误

出现这种错误的原因是在while循环中,栈外元素大于栈顶元素的情况,在栈顶元素弹出之后并没有将新的元素放入堆栈,因此将代码修改如下

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        vector<int> result(temperatures.size(),0);
        stack<int> st;
        st.push(0);
        for(int i=1;i<temperatures.size();i++){
            while(!st.empty() && temperatures[i]>temperatures[st.top()]){
                result[st.top()]=i-st.top();
                st.pop();
                st.push(i);
            }
            if(!st.empty() && temperatures[i]<=temperatures[st.top()]) st.push(i);
        }
        return result;      
    }
};

又有新的错误出现了

原因是while循环代表着,栈外元素一直比栈顶元素大,那么一直弹出栈顶元素,直到小于等于为止,这个过程不应该将栈外元素放入堆栈,将栈外元素放入堆栈的操作应在整个while循环都遍历完成后才进行,因此,可以将代码改为如下,因为栈外元素大于等于栈顶元素的时候,一定是要放入堆栈的,所以这两步操作可以合并起来,就是没有这个if限制条件了,只要不满足栈外元素大于栈顶元素了,就将栈外元素放入堆栈,这时代码才可以正常通过·

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        vector<int> result(temperatures.size(),0);
        stack<int> st;
        st.push(0);
        for(int i=1;i<temperatures.size();i++){
            while(!st.empty() && temperatures[i]>temperatures[st.top()]){
                result[st.top()]=i-st.top();
                st.pop();
            }
            st.push(i);
        }
        return result;      
    }
};

题目2:496 下一个更大元素Ⅰ

题目链接:下一个更大元素Ⅰ

对题目的理解

两个数组nums1和nums2无重复元素,nums1是nums2的子集,找满足nums1[i]==nums2[j]的下标j,(即在数组nums2中,找出与nums1中相同元素的下标),并在nums2确定nums2[j]的下一个更大元素,如果不存在,则返回1

nums1中x的下一个更大元素是指:x在nums2中对应位置右侧的第一个比x大的元素

nums1和nums2至少包含一个元素

常规思路

常规思路,求出nums1中的元素在nums2中相等的下标,然后根据这个下标数组遍历nums2进行查找,但是卡死了,一直报错误

代码(卡死了)

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {       
        vector<int> index(nums1.size(),0);
        for(int i=0;i<nums1.size();i++){
            for(int j=0;j<nums2.size();j++){
                if(nums1[i]==nums2[j]) index.push_back(j);
            }//使用index存储nums2中的下标4,7,8,9
        }
        vector<int> result(nums1.size(),-1);
        stack<int> st;
        for(int i=0;i<index.size();i++){
            while(!st.empty() && nums2[index[i]]>nums2[st.top()]){
                result[]=nums2[index[i]];
                st.pop();
            }
            st.push(index[i]);
        }
        return result;
    }
};

单调栈

注意题目中说是两个没有重复元素 的数组 nums1 和 nums2,没有重复元素,就可以用map来做映射了。根据数值快速找到下标,还可以判断nums2[i]是否在nums1中出现过,C++中,使用集合来解决哈希问题的时候,优先使用unordered_set,因为它的查询和增删效率是最优的

分析如下三种情况:

情况一:当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况,此时满足递增栈(栈头到栈底的顺序),所以直接入栈。

情况二:当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况,如果相等的话,依然直接入栈,求的是右边第一个比自己大的元素,而不是大于等于!

情况三:当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况,判断栈顶元素是否在nums1里出现过,(注意栈里的元素是nums2的元素),如果出现过,开始记录结果。

伪代码

代码(注意一定要是nums2[st.top()]

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {       
        vector<int> result(nums1.size(),-1);//初始化为-1
        stack<int> st;
        //定义一个哈希表,来映射nums1的元素与下标的关系
        unordered_map<int,int> umap;
        for(int i=0;i<nums1.size();i++){
            umap[nums1[i]]=i;//元素  位置,后续nums2根据与nums1中相同的元素,找到该位置i,更新该处的数值
        }
        st.push(0);
        for(int i=1;i<nums2.size();i++){
            while(!st.empty() && nums2[i]>st.top()){//如果出现元素大于的情况
                //如果这个元素在nums1中
                if(umap.count(st.top())>0){
                    int index=umap[st.top()];//获取这个元素在的位置,最上面for循环的i
                    result[index]=nums2[i];
                }
                st.pop();
            }
            st.push(nums2[i]);
        }
        return result;
    }
};

!!!注意st栈中放的是下标,是下标,是下标,重要的事情说三遍,使用的时候需要将该下标带入数组,一定要是nums2[st.top()],将代码改为如下就OK

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {       
        vector<int> result(nums1.size(),-1);//初始化为-1
        stack<int> st;
        //定义一个哈希表,来映射nums1的元素与下标的关系
        unordered_map<int,int> umap;
        for(int i=0;i<nums1.size();i++){
            umap[nums1[i]]=i;//元素  位置,后续nums2根据与nums1中相同的元素,找到该位置i,更新该处的数值
        }
        st.push(0);
        for(int i=1;i<nums2.size();i++){
            if(nums2[i]<nums2[st.top()]) st.push(i);
            else if(nums2[i]==nums2[st.top()]) st.push(i);
            else {
                while(!st.empty() && nums2[i]>nums2[st.top()]){//如果出现元素大于的情况
                    //如果这个元素在nums1中
                    if(umap.count(nums2[st.top()])>0){
                        int index=umap[nums2[st.top()]];//获取这个元素在的位置,最上面for循环的i
                        result[index]=nums2[i];
                    }
                    st.pop();
                }
                st.push(i);
            }
        }
        return result;
    }
};

精简代码

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {       
        vector<int> result(nums1.size(),-1);//初始化为-1
        stack<int> st;
        //定义一个哈希表,来映射nums1的元素与下标的关系
        unordered_map<int,int> umap;
        for(int i=0;i<nums1.size();i++){
            umap[nums1[i]]=i;//元素  位置,后续nums2根据与nums1中相同的元素,找到该位置i,更新该处的数值
        }
        st.push(0);
        for(int i=1;i<nums2.size();i++){
            while(!st.empty() && nums2[i]>nums2[st.top()]){//如果出现元素大于的情况
                //如果这个元素在nums1中
                if(umap.count(nums2[st.top()])>0){
                    int index=umap[nums2[st.top()]];//获取这个元素在的位置,最上面for循环的i
                    result[index]=nums2[i];
                }
                st.pop();
            }
            st.push(i);
        }
        return result;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/227382.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

论文精读 MOG2 阴影检测

An Improved Adaptive Background Mixture Model for Real-time Tracking with Shadow Detection 一种用于阴影检测实时跟踪的改进自适应背景混合模型 承接上一篇博客&#xff1a;论文精读 && MOG && 埃里克格里姆森-CSDN博客 目录 一、摘要 二、结论 三…

Spring Boot HTTP 400 错误的日志信息在哪里查看 ?

HTTP 400 一般来说是入参的某些字段的格式不对 Spring Boot项目启动后默认是不会把相应的日志打印在控制台的 需要在logback.xml里面做相关的配置才会打印出来 具体配置如下 <configuration><appender name"stdout" class"ch.qos.logback.core.Con…

西南科技大学C++程序设计实验九(多态二)

Point operator++ (int) { // 后置自增运算符重载 Point temp(*this); ++(*this); return temp; } void print() { cout << "x=" << x << ", y=" << y << endl; } private: int x; int y; }; int main() { P…

谷歌Gemini AI模型使用指南

引言 2023年12月7日&#xff0c;谷歌宣布推出其迄今为止功能最强大、最通用的多模态人工智能&#xff08;AI&#xff09;大模型&#xff1a;Gemini。根据最新的性能评估&#xff0c;Gemini在多项指标上已经超越了ChatGPT 4。 Gemini的使用教程 Gemini 模型从大到小分为Ultra…

[Linux] nginx配置的主配置文件

一、六个模块的作用 全局块&#xff1a;全局配置&#xff0c;对全局生效&#xff1b; events块&#xff1a;配置影响 Nginx 服务器与用户的网络连接&#xff1b; http块&#xff1a;配置代理&#xff0c;缓存&#xff0c;日志定义等绝大多数功能和第三方模块的配置&#xff1b;…

【VRTK】【VR开发】【Unity】11-甩臂移动

课程配套学习资源下载 https://download.csdn.net/download/weixin_41697242/88485426?spm=1001.2014.3001.5503 【概述】 除了一般的移动能力,VRTK还提供更为沉浸的甩臂移动。 【设定摇杆输入中间件】 在Hierarchy中展开Button Input Actions,其下生成两个新的空子对象…

【Flink系列四】Window及Watermark

3.1、window 在 Flink 中 Window 可以将无限流切分成有限流&#xff0c;是处理有限流的核心组件&#xff0c;现在 Flink 中 Window 可以是时间驱动的&#xff08;Time Window&#xff09;&#xff0c;也可以是数据驱动的&#xff08;Count Window&#xff09;。 Flink中的窗口…

翻译: 生成式人工智能的经济潜力 第2部分行业影响 The economic potential of generative AI

麦肯锡报告 翻译: 生成式人工智能的经济潜力 第一部分商业价值 The economic potential of generative AI 1. 行业影响 在我们分析的63个使用案例中&#xff0c;生成式人工智能有潜力在各行各业创造2.6万亿至4.4万亿美元的价值。其确切影响将取决于各种因素&#xff0c;比如…

Qt之QGraphicsView —— 笔记1:绘制简单图元(附完整源码)

效果 相关类介绍 QGraphicsView类提供了一个小部件,用于显示QGraphicsScene的内容。QGraphicsView在可滚动视口中可视化。QGraphicsView将滚动其视口,以确保该点在视图中居中。 QGraphicsScene类 提供了一个用于管理大量二维图形项的场景。请注意,QGraphicsScene没有自己的视…

Open-Falcon(一)环境配置

目录 ip划分一、主机准备二、环境配置2.1修改主机名、修改hosts文件2.2配置阿里源&#xff0c;安装工具2.3关闭防火墙、selinux2.4配置时间2.5安装go2.6安装redis2.7 安装mysql初始化MySQL表结构 ip划分 主机名IP服务open-faclon-server192.168.150.200open-faclon-serverngin…

nodejs微信小程序+python+PHP的智能停车系统-计算机毕业设计推荐django

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

select*from 查询语句返回null

1. 写了一个很简单查询全部数据的demo接口,结果一直返回null. 数据库明明有数据而且在console控制台也可以查到,但是用接口访问一直返回null 2.后发现原来是数据库中字段名和对象的属性名称对不上&#xff0c;所以可以在yml文件中加上 mybatis:configuration:map-underscore-…

如何搭建一套完整的智能安防视频监控平台?关于设备与软件选型的几点建议

安防视频监控系统主要由前端摄像机设备、视频显示设备、视频存储设备、安防应用软件/平台以及其它传输、辅助类设备组成。一般来说&#xff0c;安防监控系统具有可扩展和开放性&#xff0c;以方便未来的扩展和与其他系统的集成。今天我们就来介绍一下&#xff0c;搭建一套完整的…

Kubersphere应用【四】创建SpringBoot项目

一、生成Springboot项目 【地址】https://start.spring.io/ Spring在线生成项目工具&#xff0c;可以快速生成Spring Boot项目。选择要的依赖项&#xff0c;填写基本信息&#xff0c;点击【GENERATE】就可以生成一个可运行的Spring Boot项目。 二、IDEA导入项目 生成项目后,进…

LAMP和分离式LNMP部署

目录 一.什么是LAMP&#xff1f; 二.安装LAMP 先安装apache&#xff0c;httpd网页服务&#xff1a; 接着安装mysql&#xff1a; 安装php&#xff1a; 创建论坛&#xff1a; 三.安装分布式LNMP&#xff1a; 先安装nginx&#xff1a; 到另一台主机安装php&#xff1a; …

dtm分布式事务框架之SAGA 实战

一.dtm分布式事务框架之SAGA 1.1DTM介绍 DTM是一款开源的分布式事务管理器&#xff0c;解决跨数据库、跨服务、跨语言栈更新数据的一致性问题。 通俗一点说&#xff0c;DTM提供跨服务事务能力&#xff0c;一组服务要么全部成功&#xff0c;要么全部回滚&#xff0c;避免只更…

javaTCP协议实现一对一聊天

我们首先要完成服务端&#xff0c;不然出错&#xff0c;运行也要先运行服务端&#xff0c;如果不先连接服务端&#xff0c;就不监听&#xff0c;那客户端不知道连接谁 服务端 import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.Actio…

ncnn模型部署——使用VS2019把项目打包成DLL文件

一、项目打包成DLL文件 1.创建动态链接库DLL项目 创建完成&#xff0c;项目中包含源文件dllmain.cpp, pch.cpp&#xff0c;头文件framework.h, pch.h 2.编写和配置DLL项目 &#xff08;1&#xff09;配置pch.h文件&#xff0c;在头文件pch.h中定义宏&#xff0c;宏的作用的是…

gma 空间绘图实战(1):绘制多个子图,连接并展示局部放大区域

安装 gma&#xff1a;pip install gma 本文基于&#xff1a;gma 2.0.3&#xff0c;Python 3.10 本文用到的矢量数据为&#xff1a;CTAmap 1.12。来源于 https://www.shengshixian.com/ 。&#xff08;感谢锐多宝&#xff09; 绘图目标 参考代码 import matplotlib.pyplot as p…

电子秤ADC芯片CS1237技术资料问题合集

问题11&#xff1a;实际应用中&#xff0c;多个称重传感器应该怎么与ADC连接&#xff1f; 解答&#xff1a;如果传感器是测量同一物体&#xff08;例如&#xff1a;厨房垃圾处理器&#xff09;&#xff0c;一般建议使用并联的方式。则相同类型的信号线连接在一起。对于传感器的…