LeetCode題目
- 1、括號匹配問題
- 2、用隊列實現棧
- 3、用棧實現隊列
- 4、設計循環隊列
1、括號匹配問題
LeetCode鏈接: 【20. 有效的括號】
這道題就是經典的利用棧解決問題的例子;思路如下:
遍歷一遍字符串,如果遇倒左括號就入棧,如果遇倒右括號取棧頂的元素進行匹配并出棧頂的元素,如果相匹配就繼續,不匹配就返回false。
但是要注意這樣只能檢驗出左右括號個數相等的情況下才可以,如果左右括號個數不相等呢?
- 如果左括號多于右括號,并且遍歷結束后它們都是匹配的,這種情況并不是完全匹配的,因為棧里還有元素剩余;所以遍歷字符串后要加一個判斷棧是否為空,只要棧為空了才是全部匹配完,沒有剩余。 比如:“[[[[[((()))”
- 如果右括號多余左括號,有可能導致棧是空的,棧里面沒有元素可以取了,這種情況也是不匹配的;所以取棧頂元素的前面要加一個判斷棧是否為空,如果棧為空說明右括號多余左括號,是不匹配的。比如:”((([[[ ]]]]]]]]]"
代碼實現如下:
typedef char STDataType
;
struct Stack
{STDataType
* a
;int top
;int capacity
;
};
typedef struct Stack ST
;
void StackInit(ST
* ps
);
void StackDestroy(ST
* ps
);
void StackPush(ST
* ps
, STDataType x
);
void StackPop(ST
* ps
);
int StackSize(ST
* ps
);
STDataType
StackTop(ST
* ps
);
bool
StackEmpty(ST
* ps
);void StackInit(ST
* ps
)
{ps
->a
= NULL;ps
->capacity
= 0;ps
->top
= 0;
}void StackDestroy(ST
* ps
)
{free(ps
->a
);ps
->a
= NULL;ps
->capacity
= ps
->top
= 0;
}void StackPush(ST
* ps
,STDataType x
)
{assert(ps
);if (ps
->capacity
== ps
->top
){ps
->capacity
= ps
->capacity
> 0 ? ps
->capacity
* 2 : 2;STDataType
* tmp
= (STDataType
*)realloc(ps
->a
, ps
->capacity
* sizeof(STDataType
));if (tmp
== NULL){return;}else{ps
->a
= tmp
;}}ps
->a
[ps
->top
] = x
;ps
->top
++;
}void StackPop(ST
* ps
)
{assert(ps
);assert(ps
->top
> 0);ps
->top
--;
}int StackSize(ST
* ps
)
{assert(ps
);assert(ps
->top
> 0);return ps
->top
;
}STDataType
StackTop(ST
* ps
)
{assert(ps
);assert(ps
->top
> 0);return ps
->a
[ps
->top
- 1];
}bool
StackEmpty(ST
* ps
)
{assert(ps
);return ps
->top
== 0;
}bool
isValid(char * s
){ST st
;StackInit(&st
);while(*s
!='\0'){switch(*s
){case '(':case '[':case '{':StackPush(&st
,*s
);s
++;break;case ')':case ']':case '}':if(StackEmpty(&st
)){StackDestroy(&st
);return false
;}char top
=StackTop(&st
);StackPop(&st
);if(top
=='(' && *s
==')' || top
=='[' && *s
==']' ||top
=='{' && *s
=='}'){s
++;}else{StackDestroy(&st
);return false
;}}}if(StackEmpty(&st
)){StackDestroy(&st
);return true
;}else{StackDestroy(&st
);return false
;}}
2、用隊列實現棧
LeetCode鏈接: 【225. 用隊列實現棧】
思路: 這是要我們利用隊列的性質去實現棧,隊列的性質是先入先出,而棧的性質是后入先出;
所以我們利用兩個隊列來實現棧,一個為空隊列,一個不為空隊列;入棧:就往不為空的隊列里面入,而 出棧就是: 只保留不為空的隊列的最后一個元素,前面的元素都插入空隊列中;然后再把最后一個元素出掉就是出棧了。
代碼實現如下:
typedef int DataType
;
typedef struct Node
{struct Node* next
;DataType data
;
}Node
;typedef struct Queue
{Node
* phead
;Node
* tail
;
}Queue
;
void QueueInit(Queue
* pq
);
void QueueDestroy(Queue
* pq
);
void QueuePush(Queue
* pq
,DataType x
);
void QueuePop(Queue
* pq
);
DataType
QueueBack(Queue
* pq
);
DataType
QueueFront(Queue
* pq
);
int QueueSize(Queue
* pq
);
bool
QueueEmpty(Queue
* pq
);void QueueInit(Queue
* pq
)
{assert(pq
);pq
->phead
= NULL;pq
->tail
= NULL;
}void QueuePush(Queue
* pq
, DataType x
)
{Node
* tmp
= (Node
*)malloc(sizeof(Node
));if (tmp
== NULL){perror("malloc ");exit(-1);}tmp
->data
= x
;tmp
->next
= NULL;if (pq
->tail
== NULL){pq
->phead
= tmp
;pq
->tail
= tmp
;}else{pq
->tail
->next
= tmp
;pq
->tail
= tmp
;}
}void QueuePop(Queue
* pq
)
{assert(pq
);assert(pq
->phead
);if (pq
->phead
->next
== NULL){free(pq
->phead
);pq
->phead
= NULL;pq
->tail
= NULL;}else{Node
* tmp
= pq
->phead
->next
;free(pq
->phead
);pq
->phead
= tmp
;}
}int QueueSize(Queue
* pq
)
{assert(pq
);int count
= 0;Node
* cur
= pq
->phead
;while (cur
!= NULL){cur
= cur
->next
;count
++;}return count
;
}bool
QueueEmpty(Queue
* pq
)
{assert(pq
);return pq
->phead
== NULL;
}DataType
QueueFront(Queue
* pq
)
{assert(pq
);assert(pq
->phead
);return pq
->phead
->data
;
}DataType
QueueBack(Queue
* pq
)
{assert(pq
);assert(pq
->phead
);return pq
->tail
->data
;
}void QueueDestroy(Queue
* pq
)
{assert(pq
);Node
* tmp
= pq
->phead
;while (tmp
!= NULL){Node
* next
= tmp
->next
;free(tmp
);tmp
= next
;}pq
->phead
= pq
->tail
= NULL;
}
typedef struct {Queue q1
;Queue q2
;
} MyStack
;MyStack
* myStackCreate() {MyStack
* tmp
=(MyStack
*)malloc(sizeof(MyStack
));if(tmp
==NULL){perror("erron ");exit(-1);}QueueInit(&tmp
->q1
);QueueInit(&tmp
->q2
);return tmp
;
}
void myStackPush(MyStack
* obj
, int x
) {Queue
* empty
=&obj
->q1
;Queue
* nonempty
=&obj
->q2
;if(QueueEmpty(&obj
->q2
)){Queue
* empty
=&obj
->q2
;Queue
* nonempty
=&obj
->q1
;}QueuePush(nonempty
,x
);}
int myStackPop(MyStack
* obj
) {Queue
* empty
=&obj
->q1
;Queue
* nonempty
=&obj
->q2
;if(QueueEmpty(&obj
->q2
)){empty
=&obj
->q2
;nonempty
=&obj
->q1
;}while(QueueSize(nonempty
)>1){QueuePush(empty
,QueueFront(nonempty
));QueuePop(nonempty
);}int tmp
=QueueBack(nonempty
);QueuePop(nonempty
);return tmp
;}
int myStackTop(MyStack
* obj
) {Queue
* empty
=&obj
->q1
;Queue
* nonempty
=&obj
->q2
;if(QueueEmpty(&obj
->q2
)){empty
=&obj
->q2
;nonempty
=&obj
->q1
;}return QueueBack(nonempty
);
}bool
myStackEmpty(MyStack
* obj
) {return QueueEmpty(&obj
->q1
) && QueueEmpty(&obj
->q2
);
}void myStackFree(MyStack
* obj
) {QueueDestroy(&obj
->q1
);QueueDestroy(&obj
->q2
);free(obj
);
}
3、用棧實現隊列
LeetCode鏈接: 【232. 用棧實現隊列】
思路分析如下:
代碼實現如下:
typedef int STDataType
;
struct Stack
{STDataType
* a
;int top
;int capacity
;
};
typedef struct Stack ST
;
void StackInit(ST
* ps
);
void StackDestroy(ST
* ps
);
void StackPush(ST
* ps
, STDataType x
);
void StackPop(ST
* ps
);
int StackSize(ST
* ps
);
STDataType
StackTop(ST
* ps
);
bool
StackEmpty(ST
* ps
);void StackInit(ST
* ps
)
{ps
->a
= NULL;ps
->capacity
= 0;ps
->top
= 0;
}void StackDestroy(ST
* ps
)
{free(ps
->a
);ps
->a
= NULL;ps
->capacity
= ps
->top
= 0;
}void StackPush(ST
* ps
,STDataType x
)
{assert(ps
);if (ps
->capacity
== ps
->top
){ps
->capacity
= ps
->capacity
> 0 ? ps
->capacity
* 2 : 2;STDataType
* tmp
= (STDataType
*)realloc(ps
->a
, ps
->capacity
* sizeof(STDataType
));if (tmp
== NULL){return;}else{ps
->a
= tmp
;}}ps
->a
[ps
->top
] = x
;ps
->top
++;
}void StackPop(ST
* ps
)
{assert(ps
);assert(ps
->top
> 0);ps
->top
--;
}int StackSize(ST
* ps
)
{assert(ps
);assert(ps
->top
> 0);return ps
->top
;
}STDataType
StackTop(ST
* ps
)
{assert(ps
);assert(ps
->top
> 0);return ps
->a
[ps
->top
- 1];
}bool
StackEmpty(ST
* ps
)
{assert(ps
);return ps
->top
== 0;
}
typedef struct {ST Pushst
; ST Popst
;
} MyQueue
;MyQueue
* myQueueCreate() {MyQueue
* tmp
=(MyQueue
*)malloc(sizeof(MyQueue
));if(tmp
==NULL){perror("erron ");exit(-1);}StackInit(&tmp
->Pushst
);StackInit(&tmp
->Popst
);return tmp
;
}void myQueuePush(MyQueue
* obj
, int x
) {StackPush(&obj
->Pushst
,x
);
}
int myQueuePop(MyQueue
* obj
) {if(StackEmpty(&obj
->Popst
)){while(!StackEmpty(&obj
->Pushst
)){StackPush(&obj
->Popst
,StackTop(&obj
->Pushst
));StackPop(&obj
->Pushst
);}}int tmp
=StackTop(&obj
->Popst
);StackPop(&obj
->Popst
);return tmp
;
}
int myQueuePeek(MyQueue
* obj
) {if(StackEmpty(&obj
->Popst
)){while(!StackEmpty(&obj
->Pushst
)){StackPush(&obj
->Popst
,StackTop(&obj
->Pushst
));StackPop(&obj
->Pushst
);}}return StackTop(&obj
->Popst
);
}bool
myQueueEmpty(MyQueue
* obj
) {return StackEmpty(&obj
->Pushst
) && StackEmpty(&obj
->Popst
);
}void myQueueFree(MyQueue
* obj
) {StackDestroy(&obj
->Pushst
);StackDestroy(&obj
->Pushst
);free(obj
);
}
4、設計循環隊列
LeetCode鏈接: 【622. 設計循環隊列】
做這道題之前,我們先來了解什么是循環隊列?它的解釋如下:
循環隊列是把順序隊列首尾相連,把存儲隊列元素的表從邏輯上看成一個環,成為循環隊列。
循環隊列就是將隊列存儲空間的最后一個位置繞到第一個位置,形成邏輯上的環狀空間,供隊列循環使用。在循環隊列結構中,當存儲空間的最后一個位置已被使用而再要進入隊運算時,只需要存儲空間的第一個位置空閑,便可將元素加入到第一個位置,即將存儲空間的第一個位置作為隊尾。
循環隊列可以更簡單防止偽溢出的發生,但隊列大小是固定的。
所以循環隊列的結構搞清楚了,寫起來就比較簡單了,循環隊列有兩種實現方式,可以使用數組實現,也可以使用循環鏈表實現。下面分別來介紹。
鏈表實現如下:
typedef struct Node
{struct Node* next
;int data
;
}Node
;
typedef struct {Node
* front
;Node
* tail
;
} MyCircularQueue
;
MyCircularQueue
* myCircularQueueCreate(int k
) {MyCircularQueue
* tmp
=(MyCircularQueue
*)malloc(sizeof(MyCircularQueue
));Node
* head
=(Node
*)malloc(sizeof(Node
));Node
* a
=head
;Node
* tail
=head
;while(k
--){a
=tail
;tail
=(Node
*)malloc(sizeof(Node
));a
->next
=tail
;}tail
->next
=head
;tmp
->front
=head
;tmp
->tail
=head
;return tmp
;}
bool
myCircularQueueEnQueue(MyCircularQueue
* obj
, int value
) {if(obj
->tail
->next
==obj
->front
){return false
;}obj
->tail
->data
=value
;obj
->tail
=obj
->tail
->next
;return true
;}
bool
myCircularQueueDeQueue(MyCircularQueue
* obj
) {if(obj
->front
==obj
->tail
){return false
;}obj
->front
=obj
->front
->next
;return true
;}
int myCircularQueueFront(MyCircularQueue
* obj
) {if(obj
->front
==obj
->tail
){return -1;}return obj
->front
->data
;}
int myCircularQueueRear(MyCircularQueue
* obj
) {if(obj
->front
==obj
->tail
){return -1;}Node
* cur
=obj
->front
;while(cur
->next
!=obj
->tail
){cur
=cur
->next
;}return cur
->data
;}
bool
myCircularQueueIsEmpty(MyCircularQueue
* obj
) {return obj
->front
==obj
->tail
;}
bool
myCircularQueueIsFull(MyCircularQueue
* obj
) {return obj
->tail
->next
==obj
->front
;}
void myCircularQueueFree(MyCircularQueue
* obj
) {Node
* cur
=obj
->front
;while(cur
!=obj
->tail
){Node
* next
=cur
->next
;free(cur
);cur
=next
;}free(cur
);free(obj
);
}
數組方式實現如下:
代碼實現如下:
typedef struct {int* a
;int maxSize
;int head
;int tail
;
} MyCircularQueue
;bool
myCircularQueueIsFull(MyCircularQueue
* obj
);
MyCircularQueue
* myCircularQueueCreate(int k
) {MyCircularQueue
* tmp
=(MyCircularQueue
*)malloc(sizeof(MyCircularQueue
)); int* arr
=(int*)malloc(sizeof(int)*(k
+1));tmp
->a
=arr
;tmp
->maxSize
=k
+1;tmp
->head
=0;tmp
->tail
=0;return tmp
;
}
bool
myCircularQueueEnQueue(MyCircularQueue
* obj
, int value
) {if(myCircularQueueIsFull(obj
)){return false
;}obj
->a
[obj
->tail
]=value
;obj
->tail
++;if(obj
->tail
==obj
->maxSize
){obj
->tail
=0;}return true
;
}
bool
myCircularQueueDeQueue(MyCircularQueue
* obj
) {if(obj
->head
==obj
->tail
){return false
;}obj
->head
++;if(obj
->head
==obj
->maxSize
){obj
->head
=0;}return true
;
}
int myCircularQueueFront(MyCircularQueue
* obj
) {if(obj
->head
==obj
->tail
){return -1;}return obj
->a
[obj
->head
];}
int myCircularQueueRear(MyCircularQueue
* obj
) {if(obj
->head
==obj
->tail
){return -1;}int i
=0;if(obj
->tail
==0){i
=obj
->maxSize
-1;}else{i
=obj
->tail
-1;}return obj
->a
[i
];
}
bool
myCircularQueueIsEmpty(MyCircularQueue
* obj
) {return obj
->head
==obj
->tail
;
}
bool
myCircularQueueIsFull(MyCircularQueue
* obj
) {int head
=0;if(obj
->head
==0){head
=obj
->maxSize
-1;}else{head
=obj
->head
-1;}return head
==obj
->tail
;}void myCircularQueueFree(MyCircularQueue
* obj
) {free(obj
->a
);free(obj
);
}
總結
以上是生活随笔為你收集整理的【LeetCode之栈和队列】:关于栈和队列经典的OJ题(用C语言实现,附图详解)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。