• 【LeetCode】剑指 Offer 09. 用两个栈实现队列


    【题目描述】

    用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

    示例 1:

    输入:
    ["CQueue","appendTail","deleteHead","deleteHead"]
    [[],[3],[],[]]
    输出:[null,null,3,-1]
    示例 2:

    输入:
    ["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
    [[],[],[5],[2],[],[]]
    输出:[null,-1,null,null,5,2]
    提示:

    1 <= values <= 10000
    最多会对 appendTail、deleteHead 进行 10000 次调用

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof

    【解题思路】

    用两个栈实现队列:

    • 栈无法实现队列功能: 栈底元素(对应队首元素)无法直接删除,需要将上方所有元素出栈。
    • 双栈可实现列表倒序: 设有含三个元素的栈 A = [1,2,3] 和空栈 B = []。若循环执行 A 元素出栈并添加入栈 B ,直到栈 A 为空,则 A = [] , B = [3,2,1],即 栈 B 元素实现栈 A 元素倒序 。
    • 利用栈 B 删除队首元素: 倒序后,B 执行出栈则相当于删除了 A 的栈底元素,即对应队首元素。

    【提交代码】

      1 typedef struct st_stack{
      2     int size;
      3     int *data;
      4     int top;    
      5 }T_Stack;
      6 
      7 typedef struct {
      8     T_Stack *s1;
      9     T_Stack *s2;
     10 } CQueue;
     11 
     12 
     13 int StackInit( T_Stack *ptStack, int *data, int size)
     14 {
     15     ptStack->size = size;
     16     ptStack->data = data;
     17     ptStack->top = 0;
     18 
     19     return 0;
     20 }
     21 
     22 int StackPush( T_Stack *ptStack, int data )
     23 {
     24     if( ptStack->top == ptStack->size )
     25     {
     26         return -1;
     27     }
     28     
     29     ptStack->data[ptStack->top++] = data;
     30 
     31     return 0;
     32 }
     33 
     34 int StackPop( T_Stack *ptStack, int *data )
     35 {
     36     if( ptStack->top == 0 )
     37     {
     38         return -1;
     39     }
     40 
     41     *data = ptStack->data[--ptStack->top];
     42 
     43     return 0;
     44 }
     45 
     46 int StackTop( T_Stack *ptStack, int *data )
     47 {
     48     if( ptStack->top == 0 )
     49     {
     50         return -1;
     51     }
     52 
     53     *data = ptStack->data[ptStack->top - 1];
     54 
     55     return 0;
     56 }
     57 
     58 int StackIsEmpty( T_Stack *ptStack )
     59 {
     60     return ( ptStack->top == 0 );
     61 }
     62 
     63 int StackIsFull( T_Stack *ptStack )
     64 {
     65     return ( ptStack->top == ptStack->size );
     66 }
     67 
     68 #define QUEUE_SIZE_MAX      ( 10000 )
     69 
     70 CQueue* cQueueCreate() {
     71     int *data1;
     72     int *data2;
     73     T_Stack *s1;
     74     T_Stack *s2;
     75     CQueue *queue;
     76 
     77     data1 = (int *)malloc( sizeof(int) * QUEUE_SIZE_MAX );
     78     data2 = (int *)malloc( sizeof(int) * QUEUE_SIZE_MAX );
     79 
     80     s1 = (T_Stack *)malloc( sizeof(T_Stack));
     81     s2 = (T_Stack *)malloc( sizeof(T_Stack));
     82 
     83     StackInit( s1, data1, QUEUE_SIZE_MAX );
     84     StackInit( s2, data2, QUEUE_SIZE_MAX );
     85 
     86     queue = (CQueue *)malloc( sizeof(CQueue) );
     87 
     88     queue->s1 = s1;
     89     queue->s2 = s2;
     90 
     91     return queue;
     92 }
     93 
     94 int cQueueAppendTail(CQueue* obj, int value) {
     95     if( StackIsFull( obj->s1) ) 
     96     {
     97         return -1;
     98     }
     99 
    100     if( StackPush( obj->s1, value ) != 0 )
    101     {
    102         return -1;
    103     }
    104 
    105     return 0;
    106 }
    107 
    108 int cQueueDeleteHead(CQueue* obj) {
    109     int tmp;
    110 
    111     // 1.当B不为空,则B中仍有已完成倒叙的元素,因此直接返回B的栈顶元素
    112     if( !StackIsEmpty( obj->s2 ) )
    113     {
    114         if( StackPop( obj->s2, &tmp ) != 0)
    115         {
    116             return -1;
    117         }
    118 
    119         return tmp;
    120     }
    121 
    122     // 2.当A也为空,则两个栈都为空,无元素,因此返回-1
    123     if( StackIsEmpty( obj->s1 ) )
    124     {
    125         return -1;
    126     }
    127 
    128     // 3.将A元素全部转移至栈B中,实现元素倒叙,并返回栈B的栈顶元素
    129     while( !StackIsEmpty( obj->s1) && !StackIsFull( obj->s2 ) )
    130     {
    131         StackPop( obj->s1, &tmp );
    132         StackPush( obj->s2, tmp );
    133     }
    134 
    135     if( !StackIsEmpty( obj->s1) ) // 如果A没有完全转移,则还是错误的
    136     {
    137         return -1;
    138     }
    139 
    140     StackPop( obj->s2, &tmp );
    141 
    142     return tmp;
    143 }
    144 
    145 void cQueueFree(CQueue* obj) {
    146     free(obj->s1->data);
    147     free(obj->s2->data);
    148     free(obj->s1);
    149     free(obj->s2);
    150     free(obj);
    151 }
    152 
    153 /**
    154  * Your CQueue struct will be instantiated and called as such:
    155  * CQueue* obj = cQueueCreate();
    156  * cQueueAppendTail(obj, value);
    157  
    158  * int param_2 = cQueueDeleteHead(obj);
    159  
    160  * cQueueFree(obj);
    161 */
  • 相关阅读:
    [2020.8.3]联想 ZUK Z2 Pro(Z2121) Magisk ROOT 纯净无推广 一键刷机 ZUI_4.0.247
    [2020.8.3]联想 K5 Note(L38012) Magisk ROOT 纯净无推广 一键刷机 ZUI_3.9.218
    [2020.8.3]联想 A5(L18011) Magisk ROOT 纯净无推广 一键刷机 ZUI_3.9.068
    [2020.8.3]联想 ZUK Edge(Z2151) Magisk ROOT 纯净无推广 一键刷机 ZUI_4.0.282
    [2020.8.3]Moto P30(XT1943-1) Magisk ROOT 纯净无推广 一键刷机 ZUI_4.0.374
    [2020.8.3]联想 Z6 青春版(L38111) Magisk ROOT 纯净无推广 一键刷机 ZUI_11.5.160
    [2020.8.3]联想 Z6(L78121) Magisk ROOT 纯净无推广 一键刷机 ZUI_11.1.262
    [2020.8.3]联想 Z5S(L78071) Magisk ROOT 纯净无推广 一键刷机 ZUI_11.5.132
    《将博客搬至CSDN》
    eclipse菜单栏隐藏
  • 原文地址:https://www.cnblogs.com/utank/p/13283989.html
Copyright © 2020-2023  润新知