题解 [484.股票价格上涨天数计算] | 豆包MarsCode AI 刷题

279 阅读3分钟

问题描述

小C是一名股票交易员,最近他关注某只股票的价格波动。给定该股票连续N天的价格列表 stockPrices,你需要为小C生成一个新列表,每个位置的值表示从那天起至少需要等待多少天才能看到价格上涨。如果没有上涨的情况,则对应位置的值为0。

例如,对于股票价格列表 [33, 34, 14, 12, 16],从第一天价格 33 开始,价格上涨发生在第二天价格 34,所以输出 1。若某天之后不再有价格上涨,则输出 0。

思路

根据题目的描述,我们需要给出每支股票的状态,即最近的上涨天数,如果没有上涨,则状态为 0

类比于最近的上升气温,这道题我们同样可以使用单调栈的思路

我们可以准备一个栈,对于每天的股票

  • 当栈为空时或者栈中股票大于当前股票时,我们将价格和天数压入栈中

  • 如果当前栈中股票小于当前股票,弹出栈中所有小于当前股票的股票,其最近的上涨天数就是自己的到当前股票的天数

正确性的证明这里使用反证法:

如果当前股票不是最近的上涨的股票,那么在今天之前,一定有一只股票的价格大于等于当前股票,那支股票就会将所有小于自己的股票弹出,所以栈中股票一定要么是那支股票之后的股票,要么是金额大于那支股票的股票,与已知矛盾。所以当前股票一定是所有被弹出股票最近的上涨的股票

解题方法

维护一个数组,记录每支股票的最近上涨天数

维护一个栈,用来实现单调栈的功能

枚举给定股票每天的价格

  • 如果当前栈为空或者栈顶价格大于当前股票价格:将当前价格和当前天数一并压入栈中

  • 否则,首先循环弹出所有价格小于当前价格的股票,对每个弹出的价格,依次根据压入天数,计算上涨天数,记录在数组中;之后将当前价格压入栈中

给定股票所有价格遍历结束后,将栈中剩余的股票价格及天数全部弹出,并依次将对应的上涨天数记录更新为 0,最后返回答案数组

复杂度

时间复杂度:

O(N)

对于给定的股票,最多进栈一次出栈一次

空间复杂度:

O(N)

记录每支股票的出栈天数,长度与给定股票的数组长度相同

代码

import java.util.*;public class Main {    public static int[] solution(int N, int[] stockPrices) {        int[] ans = new int[stockPrices.length];        Deque<Integer[]> stack = new LinkedList<>();        for (int i = 0; i < stockPrices.length; i++) {            if (stack.isEmpty() || stack.peekFirst()[1] >= stockPrices[i]) {                stack.addFirst(new Integer[]{i, stockPrices[i]});            } else if (stockPrices[i] > stack.peekFirst()[1]) {                while (!stack.isEmpty() && stockPrices[i] > stack.peek()[1]) {                    Integer[] peek = stack.pollFirst();                    ans[peek[0]] = i - peek[0];                }                stack.addFirst(new Integer[]{i, stockPrices[i]});            }        }        while (!stack.isEmpty()) {            Integer[] peek = stack.pollFirst();            ans[peek[0]] = 0;        }        return ans;    }    public static void main(String[] args) {        System.out.println(java.util.Arrays.equals(solution(5, new int[]{33, 34, 14, 12, 16}), new int[]{1, 0, 2, 1, 0}));        System.out.println(java.util.Arrays.equals(solution(6, new int[]{45, 44, 46, 43, 42, 48}), new int[]{2, 1, 3, 2, 1, 0}));        System.out.println(java.util.Arrays.equals(solution(3, new int[]{10, 9, 8}), new int[]{0, 0, 0}));    }}