Leetcode栈刷题顺序

20. 有效的括号

难度简单1402
给定一个只包括 '('')''{''}''['']' 的字符串,判断字符串是否有效。
有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。

  2. 左括号必须以正确的顺序闭合。
    注意空字符串可被认为是有效字符串。

示例 1:

输入: "()"
输出: true

示例 2:

输入: "()[]{}"
输出: true

示例 3:

输入: "(]"
输出: false

示例 4:

输入: "([)]"
输出: false

示例 5:

输入: "{[]}"
输出: true
bool isValid(char *s) {
    int len = strlen(s);
    char *stack = (char *)malloc(sizeof(char) * len);
    int top = -1, flag = 1;
    while(s[0]) {
        switch (s[0]) {
        case '(' :
        case '[':
        case '{':stack[++top] = s[0];break;
        case ')':flag = ( top != -1&&stack[top--] == '(');break;
        case ']':flag = ( top != -1&&stack[top--] == '[');break;
        case '}':flag = ( top != -1&&stack[top--] == '{');break;        
        }
        if(!flag)break;
        s++;
    }
    free(stack);
    return (flag &&top == -1);
}

20.gif

225. 用队列实现栈

难度简单122收藏分享切换为英文关注反馈

使用队列实现栈的下列操作:

  • push(x) – 元素 x 入栈
  • pop() – 移除栈顶元素
  • top() – 获取栈顶元素
  • empty() – 返回栈是否为空

注意:

  • 你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 这些操作是合法的。
  • 你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
  • 你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。

思路:利用两个队列

Push an element in stack

Pop an element from stack

解题思路:
主操作
使用的是两个循环队列,始终保持一个队列为空, 然后两个队列来回倒腾,最后一个元素就是所要的栈顶元素:

(1)myStackPush(MyStack* obj, int x)操作:
就是将元素压到不为空的一个队列里
(2)myStackPop(MyStack* obj) 操作:
就是将一个不为空的全部压到另一个为空的队列里,然后记录了最后一个,最后一个元素并没有被放到另一个队列里(当你拿出来时就判断是否为空,并没有进入第二个队列)
(3)myStackTop(MyStack* obj)操作:
同删除操作,只是记录了最后一个移动的元素值

typedef struct MyQueue{
    int *data;
    int head, tail;
    int size, cnt;
}MyQueue;

MyQueue *MyQueueCreate(int size) {
    MyQueue *q = (MyQueue *)malloc(sizeof(MyQueue));
    q->data = (int *)malloc(sizeof(int) * size);
    q->head = q->tail = 0;
    q->cnt = 0;
    q->size = size;
    return q;
}

void MyQueuePush(MyQueue *obj, int x) {
    if(obj == NULL) return ;
    if(obj->cnt == obj->size)return;
    obj->data[obj->tail++] = x;
    if(obj->tail == obj->size) obj->tail -= obj->size;//当值满的时候需,此时假溢出,应该放在开头
    obj->cnt ++;
    return;
}

int MyQueuePop(MyQueue *obj) {
    if(obj == NULL) return 0;
    if(obj->cnt == 0)return 0;
    obj->head++;
    if(obj->head==obj->size) obj->head -= obj->size;
    obj->cnt -= 1;
    return 1;
}

int MyQueueFront(MyQueue *obj) {
    return obj->data[obj->head];
}

int MyQueueEmpty(MyQueue *obj) {
    return obj->cnt == 0;
}
void MyQueueFree(MyQueue *obj) {
    if(obj == NULL) return;
    free(obj->data);
    free(obj);
    return;
}

typedef struct {
    MyQueue *q1, *q2;
} MyStack;

/** Initialize your data structure here. */

MyStack* myStackCreate() { //初始化栈
    int size = 1024;
    MyStack *s = (MyStack *)malloc(sizeof(MyStack));
    s->q1 = MyQueueCreate(size);//初始化两个队列q1和q2;
    s->q2 = MyQueueCreate(size);
    return s;
}

/** Push element x onto stack. */
void myStackPush(MyStack* obj, int x) {//压栈操作:
    if(!MyQueueEmpty(obj->q1)) {//如果q1不为空时将值压入q1中
        MyQueuePush(obj->q1, x);
    } else {//如果q1为空时将值压入p2;
        MyQueuePush(obj->q2, x);
    }
    return;
}

/** Removes the element on top of the stack and returns that element. */
int myStackPop(MyStack* obj) {//删除栈顶操作
    MyQueue *p = MyQueueEmpty(obj->q1) ? obj->q2 : obj->q1;//如果q1为空p为q2,那么q就为q1
    MyQueue *q = MyQueueEmpty(obj->q1) ? obj->q1 : obj->q2;//如果q1不为空p为q1,那么q就为q2;
    int element = MyQueueFront(p);
    MyQueuePop(p);
    while(!MyQueueEmpty(p)) {//如果不为空
        MyQueuePush(q, element);//就将删除的元素放在另一个中
        element = MyQueueFront(p);
        MyQueuePop(p);
    }
    return element;//记录的是最后一个删除的元素;
}

/** Get the top element. */
int myStackTop(MyStack* obj) {
    MyQueue *p = MyQueueEmpty(obj->q1) ? obj->q2 : obj->q1;
    MyQueue *q = MyQueueEmpty(obj->q1) ? obj->q1 : obj->q2;
    int element;
    while(!MyQueueEmpty(p)) {//同删除操作
        element = MyQueueFront(p);
        MyQueuePop(p);
        MyQueuePush(q, element);//记录最后一个元素
    }
    return element;//将最后一个元素返回
}

/** Returns whether the stack is empty. */
bool myStackEmpty(MyStack* obj) {
    return MyQueueEmpty(obj->q1) && MyQueueEmpty(obj->q2);
}

void myStackFree(MyStack* obj) {
    if(obj == NULL) return;
    MyQueueFree(obj->q1);
    MyQueueFree(obj->q2);
    return;
}

/**
 * Your MyStack struct will be instantiated and called as such:
 * MyStack* obj = myStackCreate();
 * myStackPush(obj, x);
 
 * int param_2 = myStackPop(obj);
 
 * int param_3 = myStackTop(obj);
 
 * bool param_4 = myStackEmpty(obj);
 
 * myStackFree(obj);
*/

232. 用栈实现队列

难度简单142

使用栈实现队列的下列操作:

  • push(x) – 将一个元素放入队列的尾部。
  • pop() – 从队列首部移除元素。
  • peek() – 返回队列首部的元素。
  • empty() – 返回队列是否为空。

示例:

MyQueue queue = new MyQueue();

queue.push(1);
queue.push(2);  
queue.peek();  // 返回 1
queue.pop();   // 返回 1
queue.empty(); // 返回 false

说明:

  • 你只能使用标准的栈操作 – 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
  • 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。
typedef struct MyStack {
    int *data;
    int top;
}MyStack;

MyStack *MyStackCreate(int size) {
    MyStack *s = (MyStack *)malloc(sizeof(MyStack));
    s->data = (int *)malloc(sizeof(int) * size);
    s->top = - 1;
    return s;
}

void MyStackPush(MyStack *obj, int x) {
    obj->top += 1;
    obj->data[obj->top] = x;
}

int MyStackPop(MyStack *obj) {
    return obj->data[obj->top--];
}

int MyStackTop(MyStack *obj) {
    return obj->data[obj->top];
}

int MyStackEmpty(MyStack *obj) {
    return obj->top == -1;
}

void MyStackFree(MyStack *obj) {
    if(obj == NULL) return ;
    free(obj->data);
    free(obj);
    return;
}



typedef struct {
    MyStack *s1, *s2;
} MyQueue;

/** Initialize your data structure here. */

MyQueue* myQueueCreate() {
    int size = 1024;
    MyQueue *q = (MyQueue * )malloc(sizeof(MyQueue));
    q->s1 = MyStackCreate(size);
    q->s2 =  MyStackCreate(size);
    return  q;
}

/** Push element x to the back of queue. */
void myQueuePush(MyQueue* obj, int x) {
     MyStackPush(obj->s1, x);
}

/** Removes the element from in front of queue and returns that element. */
int myQueuePop(MyQueue* obj) {
    if(MyStackEmpty(obj->s2)) {
        while(!MyStackEmpty(obj->s1)) {
            MyStackPush(obj->s2, MyStackPop(obj->s1));
        }
    }
    return MyStackPop(obj->s2);
}

/** Get the front element. */
int myQueuePeek(MyQueue* obj) {
    if(MyStackEmpty(obj->s2)) {
        while(!MyStackEmpty(obj->s1)) {
            MyStackPush(obj->s2, MyStackPop(obj->s1));
        }
    }
    return MyStackTop(obj->s2);
}

/** Returns whether the queue is empty. */
bool myQueueEmpty(MyQueue* obj) {
  return MyStackEmpty(obj->s1) && MyStackEmpty(obj->s2);
}

void myQueueFree(MyQueue* obj) {
    if(obj == NULL) return;
    free(obj->s1);
    free(obj->s2);
    free(obj);
    return;
}

/**
 * Your MyQueue struct will be instantiated and called as such:
 * MyQueue* obj = myQueueCreate();
 * myQueuePush(obj, x);
 
 * int param_2 = myQueuePop(obj);
 
 * int param_3 = myQueuePeek(obj);
 
 * bool param_4 = myQueueEmpty(obj);
 
 * myQueueFree(obj);
*/
根据引用\[1\]和引用\[2\]的内容,推荐的LeetCode刷题顺序是按照目类型刷题,优先选择树、链表、二分查找、DFS、BFS、动态规划等常见类型的目。可以先做2~4道简单,然后再做中等难度的目。在选择目时,可以优先选择目序号小、点赞多、提交成功率高的目,这样可以从简单入手,节省时间。同时,LeetCode每道目都有“模拟面试”功能,可以给自己设定时间限制,如果做不出来可以看答案,然后记住思路后再自己尝试一遍。每种类型的目做完10+道后,可以总结规律。 根据引用\[3\]的内容,目可以按照不同的分类进行刷题,比如数组与贪心算法、子数组与贪心算法、子序列与贪心算法、数字与贪心、单调法、双指针法等。可以根据自己的兴趣和需求选择相应的目进行刷题。 综上所述,LeetCode刷题顺序可以按照目类型或者目分类进行选择。 #### 引用[.reference_title] - *1* [LeetCode 刷题顺序,按标签分类,科学刷题!](https://blog.csdn.net/fengyuyeguirenenen/article/details/125099023)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [leetcode 刷题指南 & 刷题顺序](https://blog.csdn.net/qijingpei/article/details/125561071)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [leetcode-刷题顺序推荐](https://blog.csdn.net/weixin_38087674/article/details/114107841)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值