您现在的位置是:首页 >学无止境 >【刷题之路】单调栈秒解每日温度网站首页学无止境

【刷题之路】单调栈秒解每日温度

Camellia-Echo 2024-07-22 06:01:03
简介【刷题之路】单调栈秒解每日温度

一、题目描述

原题链接:https://leetcode.cn/problems/daily-temperatures/

题目描述:

给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。

 

示例 1:

输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]
示例 2:

输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]
示例 3:

输入: temperatures = [30,60,90]
输出: [1,1,0]

二、解题

方法:单调栈

思路分析:

本题靠栈这一数据结构解决更为轻松,找下一个更大或者更小元素是单调栈题目的标配

我们先来记单调栈的结论,然后再解释为什么 

结论:

  • 1.栈顶向栈底数据递增是求下一个更大元素,栈顶向栈底递减是求下一个更小元素
  • 2.单调栈的作用是记录遍历过的元素,然后与当前遍历的元素进行比较,最后再对遍历过的元素(栈内元素)进行操作

注意:这里我们往栈里存储的是下标,如果需要使用对应的元素,直接T[i]就可以获取。如果要修改对应的值,也可以通过下标找到对应位置。

  •  注意弹出的时候应该是当前遍历元素不断和栈内元素进行比较,所以这里应该要有一个循环,直到循环结束后,再将当前遍历元素入栈
  • 题目要求如果气温在这之后都不会升高,请在该位置用 0 来代替。所以遍历结束后还留在栈内的就是不会再升高的温度了,我们不对其进行任何操作,在开辟数组的时候将数组元素初始化为0即可
  • 开辟数组的时候应该使用malloc,而不是int,因为这是在函数接口内,局部变量会在调用结束后被销毁

代码实现

首先我们来cv一下c语言手撕的栈

 typedef int STDataType;
typedef struct Stack
{
	int top;
	int capacity;
	STDataType* a;
}ST;

void StackInit(ST* ps);
void StackDestroy(ST* ps);
void StackPush(ST* ps, STDataType x);
void StackPop(ST* ps);
STDataType StackTop(ST* ps);//获得栈顶元素
int StackSize(ST* ps);
bool StackEmpty(ST* ps);

void StackInit(ST* ps)
{
	assert(ps);

	ps->capacity = ps->top = 0;//指向最后一个数据的下一个
	ps->a = NULL;
}

bool StackEmpty(ST* ps)
{
	assert(ps);

	return ps->top == 0;
}
void StackPush(ST* ps, STDataType x)
{
	assert(ps);

	//当内存满了则需要扩容
	if (ps->top == ps->capacity)
	{
		int newcapacity = (ps->capacity == 0) ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a, newcapacity);
		if (tmp == NULL)
		{
			perror("malloc fail
");
			return;
		}
		else
		{
			ps->capacity = newcapacity;
			ps->a = tmp;
		}
	}
	//没满就直接压栈即可
	ps->a[ps->top] = x;
	ps->top++;
}
void StackPop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));

	ps->top--;
}
STDataType StackTop(ST* ps)//获得栈顶元素
{
	assert(ps);
	assert(!StackEmpty(ps));

	return ps->a[ps->top - 1];
}
void StackDestroy(ST* ps)
{
	assert(ps);

	free(ps->a);

	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

以下为题解

int* dailyTemperatures(int* temperatures, int temperaturesSize, int* returnSize){
    //数组初始化
    int* result = (int*)malloc(sizeof(int) * temperaturesSize);
    for(int i=0;i<temperaturesSize;i++)
    {
         result[i]=0;
    }
    ST st;
     StackInit(&st);
    *returnSize = temperaturesSize;
    StackPush(&st, 0);
    for (int i = 1;i < temperaturesSize;i++)
    {
        //小于等于栈顶元素直接入栈
        if (temperatures[i] <= temperatures[StackTop(&st)])
        {
            StackPush(&st, i);
        }
        else
        {
            //当前遍历元素大于栈顶元素,将遍历元素减去栈顶元素后放入数组里,直到栈为空
            while (!StackEmpty(&st) && temperatures[i] > temperatures[StackTop(&st)])
            {
                //后-前
                result[StackTop(&st)] = i - StackTop(&st);
                 StackPop(&st);
             }
            StackPush(&st, i);
        }
    }
    return result;  
}

三、总结

本道题目为单调栈裸题,还有不少的变形题。

希望大家能仔细体会单调栈的用法以及原理,然后再去突破其他几道单调栈的题目

下一个更大元素I

下一个更大元素II

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。