力扣(LeetCode)901. 股票价格跨度(C语言)

一、环境说明

  1. 本文是 LeetCode 901题 : 股票价格跨度,使用c语言实现。
  2. 单调栈(链栈)。
  3. 测试环境:Visual Studio 2019。

二、代码展示

typedef struct node{
    int price;//价格
    int pos;//栈顶下标
    struct node *next;//后继结点
}node;
typedef struct StockSpanner{
    int idx;//当前位置
    node *stack;//栈
} StockSpanner;//结构体
//链表——不带哑结点。头插法+头部删除,模拟栈。
node *nodeCreate(int price,int pos){//传入价格和位置
    node *newnode = (node*)calloc(1,sizeof(node));//包括新结点后继为NULL
    newnode->price = price;
    newnode->pos = pos;
    return newnode;
}
StockSpanner* stockSpannerCreate() {//初始化第一个坐标
    StockSpanner *s = (StockSpanner*)calloc(1,sizeof(StockSpanner));//初始化一个股价跨度
    node* newnode = nodeCreate(INT_MAX, -1);//初始化一个结点,价格INT_MAX,不会被超越。确保栈非空.
    s->idx = -1;//索引-1,不占用栈的索引。
    s->stack = newnode;//最初的栈
    return s;
}
//链表模拟栈
int stockSpannerNext(StockSpanner* obj, int price) {//插入新的结点
    obj->idx++;//索引++。从0开始。
    while(price>=obj->stack->price){//当前price大于等于栈顶price//由于有一个INT_MAX结点,保证栈不为空。
        node *temp = obj->stack;//初始化新结点
        obj->stack = obj->stack->next;//栈顶元素出栈。
        free(temp);//释放栈顶
    }
    int ans = obj->idx - obj->stack->pos;
    node *stacktop = nodeCreate(price,obj->idx);//创建新的栈顶结点
    stacktop->next = obj->stack;//新的栈顶后继是旧的栈顶
    obj->stack = stacktop;//更新栈
    return ans;//当前索引-栈顶元素索引//所得即所求 
}

void stockSpannerFree(StockSpanner* obj) {//释放链表
    while(obj->stack){
        node *p = obj->stack;
        obj->stack = obj->stack->next;
        free(p);
    }
    free(obj);
}

三、思路分析

  • 找价格跨度的题,如 股票区间 [ [ ] , [ 100 ] , [ 80 ] , [ 60 ] , [ 70 ] , [ 60 ] , [ 75 ] , [ 85 ] ] [[],[100],[80],[60],[70],[60],[75],[85]] [[],[100],[80],[60],[70],[60],[75],[85]],对于第 4 4 4个数字 70 70 70,我们要找的就是 80 80 80的位置,算出 70 70 70 80 80 80位置的差值 = 4 − 2 = 2 =4-2=2 =42=2,就是所求的价格跨度。
  • 上述过程,总结就是找距离当前数字 ( 70 ) (70) (70)左侧最近的较大数字 ( 80 ) (80) (80)的位置,这个过程和栈的后入先出性质类似。
  • 我们选择单调栈解题。
  • 如题,我们要建立结构体 S t o c k S p a n n e r StockSpanner StockSpanner和单调栈。我们有两种选择:
  1. S t o c k S p a n n e r StockSpanner StockSpanner存储 p r i c e price price p o s pos pos。那么我们要用数组模拟栈。栈的大小必须给定,空间复杂度太高。
  2. S t o c k S p a n n e r StockSpanner StockSpanner存储 s t a c k stack stack链表 i d x idx idx当前位置。链表存储 p r i c e price price p o s pos pos n e x t next next,用链表模拟栈。可以动态申请空间,较灵活。
  3. 博主使用链表模拟栈,即第 2 2 2种。

四、代码分析

  • 理解思路重要!
  • 欢迎读者在评论区留言,作为日更博主,看到就会回复的。

五、AC

力扣(LeetCode)901. 股票价格跨度(C语言)_第1张图片

六、复杂度分析

  1. 时间复杂度: O ( n ) O(n) O(n) , n n n是调用 n e x t next next函数的次数。
  2. 空间复杂度: O ( n ) O(n) O(n),如果股票价格降序排列,栈内最终会有 n n n个数,最坏空间复杂度 O ( n ) O(n) O(n)

你可能感兴趣的:(小白leetcode,leetcode,c语言,单调栈,数据结构,链表)