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

Posted uTank-木头

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 */

 

以上是关于LeetCode剑指 Offer 09. 用两个栈实现队列的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode(剑指 Offer)- 09. 用两个栈实现队列

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

[leetcode]剑指 Offer 09. 用两个栈实现队列

leetcode剑指 Offer 09. 用两个栈实现队列

[LeetCode]剑指 Offer 09. 用两个栈实现队列

Leetcode刷题Python剑指 Offer 09. 用两个栈实现队列