2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
ABl.-Link:225. Verwenden Sie Warteschlangen, um Stapel zu implementieren – LeetCode
Okay, werfen wir einen Blick auf den Titel. Der Titel sagt es
Ideen : Verwenden Sie zwei Warteschlangen und lassen Sie eine Warteschlange immer leer. Wenn wir die Daten auf den Stapel schieben müssen, stellen Sie die Daten in eine Warteschlange, die nicht leer ist (wenn beide leer sind, schieben Sie sie in eine beliebige Warteschlange). Wenn ein Pop-Vorgang erforderlich ist, werden die Daten in der nicht leeren Warteschlange in die leere Warteschlange importiert, sodass nur noch eine Datenmenge übrig bleibt. Zu diesem Zeitpunkt können diese Daten zurückgegeben und gelöscht werden.Bestimmen Sie, ob der Stapel leer ist, dh ob die beiden Warteschlangen gleichzeitig leer sind
Wir werden es zum Beispiel tun 1,2,3,4
In den Stapel zu schieben bedeutet eigentlich, in eine der Warteschlangen einzutretenq1
Mitte
Wenn wir den Stapel herausspringen lassen wollen, sollten wir folgen 4,3,2,1
der Reihe nach werden wir es tun1,2,3
push
in die zweite Warteschlangeq2
rein, dann reinq1
Mittepop
4
Schließen Sie den einstufigen Vorgang zum Öffnen des Stapels ab
Dann können wir push
q2
Mitte1,2
ankommenq1
, also kannst du eins hinterlassen3
existierenq2
Dannpop
q2
Das ist es3
Die Pop-Operation
Diese Schleife kann alle Vorgänge zum Öffnen des Stapels abschließen.
Hier ist die Code-Implementierung:
typedef int QDataType;
typedef struct QueueNode
{
struct QueueNode* next;
QDataType data;
}QNode;
typedef struct Queue
{
QNode* head;
QNode* tail;
int size;
}Queue;
void QueueInit(Queue* pq);
void QueueDestory(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
bool QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);
void QueueInit(Queue* pq)
{
assert(pq);
pq->size = 0;
pq->head = pq->tail = NULL;
}
void QueueDestory(Queue* pq)
{
assert(pq);
QNode* cur = pq->head;
while (cur)
{
QNode* del = cur;
cur = cur->next;
free(del);
}
pq->size = 0;
pq->head = pq->tail = NULL;
}
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc failn");
exit(-1);
}
else
{
newnode->data = x;
newnode->next = NULL;
}
if (pq->tail == NULL)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
pq->size++;
}
bool QueueEmpty(Queue* pq)
{
return pq->tail == NULL && pq->head == NULL;
}
void QueuePop(Queue* pq)
{
assert(pq);
assert(!(QueueEmpty(pq)));
if (pq->head->next == NULL)
{
free(pq->head);
pq->head = pq->tail = NULL;
}
else
{
QNode* del = pq->head;
pq->head = pq->head->next;
free(del);
del = NULL;
}
pq->size--;
}
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(!(QueueEmpty(pq)));
return pq->head->data;
}
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(!(QueueEmpty(pq)));
return pq->tail->data;
}
int QueueSize(Queue* pq)
{
assert(pq);
return pq->size;
}
typedef struct {
Queue q1;
Queue q2;
} MyStack;
MyStack* myStackCreate() {
MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
QueueInit(&obj->q1);
QueueInit(&obj->q2);
return obj;
}
void myStackPush(MyStack* obj, int x) {
if (!QueueEmpty(&obj->q1))
{
QueuePush(&obj->q1, x);
}
else
{
QueuePush(&obj->q2, x);
}
}
int myStackPop(MyStack* obj) {
Queue* empty = &obj->q1;
Queue* noEmpty = &obj->q2;
if (!QueueEmpty(&obj->q1))
{
empty = &obj->q2;
noEmpty = &obj->q1;
}
while (QueueSize(noEmpty) > 1)
{
QueuePush(empty, QueueFront(noEmpty));
QueuePop(noEmpty);
}
int top = QueueFront(noEmpty);
QueuePop(noEmpty);
return top;
}
int myStackTop(MyStack* obj) {
if (!QueueEmpty(&obj->q1))
{
return QueueBack(&obj->q1);
}
else
{
return QueueBack(&obj->q2);
}
}
bool myStackEmpty(MyStack* obj) {
return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}
void myStackFree(MyStack* obj) {
QueueDestory(&obj->q1);
QueueDestory(&obj->q2);
free(obj);
}
ABl.-Link:232. Verwenden Sie den Stack, um die Warteschlange zu implementieren – LeetCode
Okay, werfen wir einen Blick auf den Titel. Der Titel sagt es
Ideen : Verwenden Sie zwei Stapel. Der erste Stapel wird nur für die Dateneingabe und der zweite Stapel nur für die Datenausgabe verwendet.Wenn Daten ausgegeben werden müssen, der zweite Stapel jedoch leer ist, importieren Sie zunächst die Daten im ersten Stapel nacheinander in den zweiten Stapel und geben Sie dann die Daten vom zweiten Stapel aus.
Ich möchte zum Beispiel folgen 1,2,3,4
in der Reihenfolge von in die Warteschlange gestellt1,2,3,4
Um die Reihenfolge zu entfernen, können wir sie zuerst in einen Stapel legen und dann die Daten im ersten Stapel nacheinander in den zweiten Stapel importieren und einfach eingeben
Hier ist die Code-Implementierung:
typedef int STDataType;
typedef struct Stack
{
STDataType* _a;
int _top; // 栈顶
int _capacity; // 容量
}Stack;
// 初始化栈
void StackInit(Stack* ps);
// 入栈
void StackPush(Stack* ps, STDataType data);
// 出栈
void StackPop(Stack* ps);
// 获取栈顶元素
STDataType StackTop(Stack* ps);
// 获取栈中有效元素个数
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool StackEmpty(Stack* ps);
// 销毁栈
void StackDestroy(Stack* ps);
bool StackEmpty(Stack* ps)
{
assert(ps);
return ps->_top == 0;
}
int StackSize(Stack* ps)
{
assert(ps);
return ps->_top;
}
STDataType StackTop(Stack* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->_a[ps->_top - 1];
}
void StackInit(Stack* ps)
{
assert(ps);
ps->_a = NULL;
ps->_capacity = ps->_top = 0;
}
void StackPush(Stack* ps, STDataType data)
{
assert(ps);
if (ps->_top == ps->_capacity)
{
int newCapacity = ps->_capacity == 0 ? 4 : ps->_capacity * 2;
STDataType* tmp = (STDataType*)realloc(ps->_a, newCapacity * sizeof(STDataType));
if (NULL == tmp)
{
perror("malloc fail");
exit(-1);
}
ps->_a = tmp;
ps->_capacity = newCapacity;
}
ps->_a[ps->_top] = data;
ps->_top++;
}
void StackPop(Stack* ps)
{
assert(ps);
ps->_top--;
}
void StackDestroy(Stack* ps)
{
assert(ps);
free(ps->_a);
ps->_a = NULL;
ps->_capacity = ps->_top = 0;
}
typedef struct {
Stack pushST;
Stack popST;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
StackInit(&obj->pushST);
StackInit(&obj->popST);
return obj;
}
void myQueuePush(MyQueue* obj, int x) {
StackPush(&obj->pushST, x);
}
void PushSTToPopST(MyQueue* obj)
{
if (StackEmpty(&obj->popST))
{
while (!StackEmpty(&obj->pushST))
{
StackPush(&obj->popST, StackTop(&obj->pushST));
StackPop(&obj->pushST);
}
}
}
int myQueuePop(MyQueue* obj) {
PushSTToPopST(obj);
int front = StackTop(&obj->popST);
StackPop(&obj->popST);
return front;
}
int myQueuePeek(MyQueue* obj) {
PushSTToPopST(obj);
int front = StackTop(&obj->popST);
return front;
}
bool myQueueEmpty(MyQueue* obj) {
return StackEmpty(&obj->popST) && StackEmpty(&obj->pushST);
}
void myQueueFree(MyQueue* obj) {
StackDestroy(&obj->pushST);
StackDestroy(&obj->popST);
free(obj);
}
ABl.-Link:20. Gültige Klammern – LeetCode
Okay, werfen wir einen Blick auf den Titel. Der Titel sagt es
Ideen: Diese Frage ist eine typische Stapelanwendung, die die Last-In-First-Out-Regel erfüllt (Die öffnende Klammer, die zuletzt auf den Stapel gelegt wird, stimmt zuerst mit der abschließenden Klammer überein, die zuerst erscheint. ). Durchlaufen Sie die Zeichenfolge und schieben Sie sie direkt auf den Stapel, wenn Sie auf die öffnende Klammer stoßen. Wenn eine hintere Klammer gefunden wird, stellen Sie fest, ob die hintere Klammer mit der vorderen Klammer oben im Stapel übereinstimmt (wenn der Stapel zu diesem Zeitpunkt leer ist, ist die Zeichenfolge ungültig. Wenn sie nicht übereinstimmt, ist die Zeichenfolge ungültig). Wenn es übereinstimmt, löschen Sie das Element oben im Stapel und fahren Sie mit dem Durchlaufen der Zeichenkette fort, bis die Zeichenfolgendurchquerung abgeschlossen ist.Überprüfen Sie beim Durchlaufen der Zeichenfolge, ob der Stapel leer ist. Wenn er nicht leer ist, bedeutet dies, dass die vordere Klammer nicht übereinstimmt und die Zeichenfolge ungültig ist.
typedef char STDataType;
typedef struct Stack
{
STDataType* _a;
int _top; // 栈顶
int _capacity; // 容量
}Stack;
// 初始化栈
void StackInit(Stack* ps);
// 入栈
void StackPush(Stack* ps, STDataType data);
// 出栈
void StackPop(Stack* ps);
// 获取栈顶元素
STDataType StackTop(Stack* ps);
// 获取栈中有效元素个数
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool StackEmpty(Stack* ps);
// 销毁栈
void StackDestroy(Stack* ps);
bool StackEmpty(Stack* ps)
{
assert(ps);
return ps->_top == 0;
}
int StackSize(Stack* ps)
{
assert(ps);
return ps->_top;
}
STDataType StackTop(Stack* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->_a[ps->_top - 1];
}
void StackInit(Stack* ps)
{
assert(ps);
ps->_a = NULL;
ps->_capacity = ps->_top = 0;
}
void StackPush(Stack* ps, STDataType data)
{
assert(ps);
if (ps->_top == ps->_capacity)
{
int newCapacity = ps->_capacity == 0 ? 4 : ps->_capacity * 2;
STDataType* tmp = (STDataType*)realloc(ps->_a, newCapacity * sizeof(STDataType));
if (NULL == tmp)
{
perror("malloc fail");
exit(-1);
}
ps->_a = tmp;
ps->_capacity = newCapacity;
}
ps->_a[ps->_top] = data;
ps->_top++;
}
void StackPop(Stack* ps)
{
assert(ps);
ps->_top--;
}
void StackDestroy(Stack* ps)
{
assert(ps);
free(ps->_a);
ps->_a = NULL;
ps->_capacity = ps->_top = 0;
}
bool isValid(char * s){
Stack st;
StackInit(&st);
while(*s)
{
if(*s == '(' || *s == '[' || *s == '{')
{
StackPush(&st, *s);
}
else
{
if(StackEmpty(&st))
{
StackDestroy(&st);
return false;
}
else
{
if((*s == ')' && StackTop(&st) != '(')
|| (*s == ']' && StackTop(&st) != '[')
|| (*s == '}' && StackTop(&st) != '{'))
{
StackDestroy(&st);
return false;
}
StackPop(&st);
}
}
++s;
}
if(!StackEmpty(&st))
{
StackDestroy(&st);
return false;
}
return true;
}
ABl.-Link:622. Zirkuläre Warteschlange entwerfen – LeetCode
Okay, werfen wir einen Blick auf den Titel. Der Titel sagt es
Ideen : Wenn in einer kreisförmigen Warteschlange die Warteschlange leer ist, zeigen Kopf und Ende der Warteschlange auf dieselbe Position. Wenn die Warteschlange nicht leer ist, zeigt der Kopf der Warteschlange auf die ersten eingefügten Daten und das Ende der Warteschlange auf die Position neben den letzten Daten. Wenn tail+1 gleich front ist, bedeutet dies, dass die Ringwarteschlange voll ist.
Beachten : Das Ende der zirkulären Warteschlange kann nicht wie das Ende der regulären Warteschlange auf die letzten Daten verweisen. In diesem Fall können wir nicht unterscheiden, ob der Status der zirkulären Warteschlange zu diesem Zeitpunkt leer oder voll ist Sowohl der Kopf als auch das Ende der Warteschlange zeigen auf dieselbe Position. Dies bedeutet, dass wir einen Raum lassen müssen, in dem keine Daten gespeichert werden können, damit wir gut unterscheiden können, ob der Status der Ringwarteschlange leer oder voll ist.
Der Implementierungscode lautet wie folgt:
typedef struct {
int* a;
int head;
int tail;
int size;
} MyCircularQueue;
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->head == obj->tail;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return (obj->tail + 1) % obj->size == obj->head;
}
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
obj->a = (int*)malloc(sizeof(int) * (k+1));
obj->head = obj->tail = 0;
obj->size = k + 1;
return obj;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if(myCircularQueueIsFull(obj))
{
return false;
}
else
{
obj->a[obj->tail] = value;
obj->tail++;
obj->tail %= obj->size;
return true;
}
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
{
return false;
}
else
{
obj->head++;
obj->head %= obj->size;
return true;
}
}
int myCircularQueueFront(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
{
return -1;
}
else
{
return obj->a[obj->head];
}
}
int myCircularQueueRear(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
{
return -1;
}
else
{
return obj->a[(obj->tail - 1 + obj->size) % obj->size];
}
}
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
free(obj);
}