描述
根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高超过该日的天数。如果之后都不会升高,请在该位置用 0 来代替。
例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。
提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。
来源:力扣(LeetCode)
链接:739. Daily Temperatures
解题思路
简单粗暴的解题思路,需要两重遍历,第一重从i开始遍历,第二重从j=i+1开始遍历,第二重遍历的时候每个数都往后看,直到找到比它大的数,找到以后记录j-i,然后跳出即可。具体代码见解法一。
当然,这种暴力解法在Leetcode上面通常是会超时的……
华丽丽地超时了:
1 2 3
| 35 / 37 个通过测试用例 状态:超出时间限制 提交时间:0 分钟之前
|
然后看了大神们的解法,又学到了,原来这道题要使用递减栈。
递减栈又叫单调栈,其定义如下:
单调栈就是栈内元素单调递增或者递减的栈,单调栈只能够在栈顶操作。
从数组的角度,单调栈具有如下性质:
- 单调栈里的元素具有单调性
- 元素加入栈前,会在栈顶端把破坏栈单调性的元素都删除
- 使用单调栈可以找到元素向左遍历第一个比他小的元素,也可以找到元素向左遍历第一个比他大的元素
- 当单调栈中的元素是单调递增的时候,根据上面我们从数组的角度阐述单调栈的性质的叙述,可以得出:
- 当a > b 时,则将元素a插入栈顶,新的栈顶则为a
- 当a < b 时,则将从当前栈顶位置向前查找(边查找,栈顶元素边出栈),停止查找,将元素a插入栈顶(在当前找到的数之后,即此时元素a找到了自己的“位置”)
- 当单调栈中的元素是单调递减的时候,则有:
- 当a < b 时,则将元素a插入栈顶,新的栈顶则为a
- 当a > b 时,则将从当前栈顶位置向前查找(边查找,栈顶元素边出栈),直到找到第一个比a大的数,停止查找,将元素a插入栈顶(在当前找到的数之后,即此时元素a找到了自己的“位置”)
本题采用单调递减栈,栈里只有递减元素,首先遍历数组,如果栈不为空,且当前数字大于栈顶元素,那么如果直接入栈的话就不是递减栈了,所以我们取出栈顶元素,那么由于当前数字大于栈顶元素的数字,而且一定是第一个大雨栈顶元素的数,那么我们直接求出下标差就是二者的距离了,然后继续看新的栈顶元素,直到当前数字小于等于栈顶元素停止,然后将数字入栈,这样就可以一直保持递减栈,且每个数字和第一个大于它的数的距离也可以算出来了,具体代码见解法二:
具体流程见下图

代码
解法一
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
int* dailyTemperatures(int* T, int TSize, int* returnSize) { int *res = (int *)malloc(sizeof(int) * TSize); for(int i = 0; i < TSize; i++) res[i] = 0; *returnSize = TSize; for(int i = 0; i < TSize; i++) { int current = T[i]; if(current < 100) { for(int j = i + 1; j < TSize; j++) { if(T[j] > current) { res[i] = j - i; break; } } } } return res; }
|
解法二
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
#define OK 0 #define NULL 0
typedef int DataType; typedef struct node{ DataType data; struct node * next; }Stack;
Stack* CreateStack() { Stack *stack = (Stack*)malloc(sizeof(Stack)); if(NULL != stack) { stack->next = NULL; return stack; } return NULL; }
void DestoryStack(Stack* stack) { free(stack); } int IsEmpty(Stack* stack) { return (stack->next == 0); }
int PushStack(Stack* stack, DataType data) { Stack* newst = (Stack*)malloc(sizeof(Stack)); if(NULL != newst) { newst->data = data; newst->next = stack->next; stack->next = newst; return 1; } return 0; }
int PopStack(Stack* stack) { Stack* tmpst; if(!IsEmpty(stack)) { tmpst = stack->next; stack->next = tmpst->next; free(tmpst); return 1; } return 0; }
int PopStackReturn(Stack* stack, DataType *data) { Stack* tmpst; if(!IsEmpty(stack)) { tmpst = stack->next; stack->next = tmpst->next; *data = tmpst->data; free(tmpst); return 1; } return 0; }
DataType GetTopElement(Stack* stack) { if(!IsEmpty(stack)) { return stack->next->data; } return -1; }
int* dailyTemperatures(int* T, int TSize, int* returnSize) { int i; int temp; int topData; int ret; int *NewT = malloc(TSize * sizeof(int)); if (NewT == NULL) { printf("malloc fail"); return NULL; } memset(NewT, 0, TSize * sizeof(int));
Stack* stack = CreateStack(); if (stack == NULL) { printf("CreateStack fail"); return NULL; } for (i = 0; i < TSize; i++) { while (!IsEmpty(stack) && (T[i] > T[GetTopElement(stack)])) { temp = GetTopElement(stack); NewT[temp] = i - temp; PopStack(stack); } PushStack(stack, i); } DestoryStack(stack); *returnSize = TSize; return NewT; }
|
参考