刷题 ------ 栈

1. 二叉树的遍历

看题名毫无疑问这肯定也是二叉树的一道题,但是我既然在栈中刷到,那么意味着用栈也是可以实现的。

(1)中序

在这里插入图片描述
方法一: 运用递归实现的。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */


// //构造一个栈出来
// int* stack = (int*)malloc(sizeof(int) * 100);
// int top = 0;
// int  gettop;

void Inorder(struct TreeNode* T,int* ans,int* size)
{
    if(T == NULL)
    {
        return;
    }

    Inorder(T->left,ans,size);

    ans[(*size)++] = T -> val;

    Inorder(T->right,ans,size);


}



int* inorderTraversal(struct TreeNode* root, int* returnSize)
{
    int* ans = (int*)malloc(sizeof(int) * 101);
    *returnSize = 0;

    Inorder(root,ans,returnSize);
    
    return  ans;
}

方法二: 迭代
这个就是利用栈来实现的

  • 中序遍历是进行左根右的遍历
  • 所以我们先将左节点全部入栈,就跟递归那样,肯定是递归进入所有的左节点。
  • 然后发现没有左节点了,将当前栈顶的元素出栈,出栈之后将根节点变成右孩子即可开始遍历右节点了
  • 整体思想上还是左根右的思想。
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* inorderTraversal(struct TreeNode* root, int* returnSize)
{
    int* ans = (int*)malloc(sizeof(int) * 101);
    *returnSize = 0;

    //构造一个栈出来
    struct TreeNode** stack = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 100);
    int top = 0;
    struct TreeNode* gettop;


    while(root != NULL || top != 0)
    {
        //将树中的左孩子入栈到底
        while(root != NULL)
        {
            stack[++top] = root;
            root = root -> left;
        }

        //出栈
        gettop = stack[top--];
        ans[(*returnSize)++] = gettop -> val;
        root = gettop -> right;

    }   
    return  ans;
}

(2)前序

在这里插入图片描述
这里就不去实现递归代码了,本章主要运用栈。

  • 前序因为是先根,所以当第一次走到该节的点时候。就该将其入ans数组了。
  • 根左,根左,根左……………………
  • 还得是左孩子走到底时候,栈顶中元素也就是它的父亲节点了。
  • 所以再去看它的右孩子就好了
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */

int* preorderTraversal(struct TreeNode* root, int* returnSize)
{
    int* ans = (int*)malloc(sizeof(int) * 100);
    *returnSize = 0;

    //栈
    struct TreeNode** stack = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 100);
    int top = 0;
    struct TreeNode* gettop;


    while(root != NULL || top != 0)
    {
        //先将根节点入栈 并且入ans数组
        while(root != NULL)
        {
            stack[++top] = root;                
            ans[(*returnSize)++] = root -> val; //根
            root = root ->left;                  //左
        }

        gettop = stack[top--];
        root = gettop -> right;                 //右
    }
    return ans;
}

(3后序

在这里插入图片描述
后序遍历更加复杂,这里增加了一个prev 用来记录上一个访问过的
同时也增加了对于右孩子的各种判断

  • 同样还是先将root 一直迭代到最左边为止,
  • 然后去判断它是否有右孩子,如果没有,就证明当前的就是左节点,将其入ans并且用prev记录下来
  • 如果没有就去迭代它的右孩子

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* postorderTraversal(struct TreeNode* root, int* returnSize)
{
    int* ans = (int*)malloc(sizeof(int) * 100);
    *returnSize = 0;

    //栈
    struct TreeNode** stack = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 100);
    int top = 0;
    struct TreeNode* gettop;                                         //prev   root 主要用于这个
    struct TreeNode* prev = NULL;           //记录前一个访问的节点, 左 右      根  

    while(root != NULL || top != 0)
    {
        while(root != NULL)
        {
            stack[++top] = root;
            root = root -> left;            
        }

        gettop = stack[top--];

        //能够到达这里 它肯定是没有左孩子的,所以判断右孩子即可:
        //(1) 判断它是否有 右孩子,           ~ 如果没有证明当前节点是左节点
        //(2) 右孩子是否 已经访问过           ~ 证明该节点就是根节点了
        if(gettop -> right == NULL || gettop -> right == prev)
        {
            ans[(*returnSize)++] = gettop -> val;
            prev = gettop;
            root = NULL;
        }
        else
        {
            //当前的getop 就是根节点 去迭代它的右孩子
            stack[++top] = gettop;
            root = gettop -> right;

        }
        
    }
    return ans;
}

2.用队列实现栈

在这里插入图片描述
用队列实现栈。。。。。。。。是的

  • 首先你得有一个队列吧。
  • 然后栈中放入两个队列
  • 对于push操作,只需要将所对应的x插入到不空的队列中去

在这里插入图片描述

  • 而对于Pop操作的话,这时候就用到那个空的队列了。将有元素的队列中除去最后一个数据,其余的全部导入到那个空的中去。
  • 然后对于Q2进行正常的GetTop操作和Pop操作就好了
    在这里插入图片描述

下面是代码,代码中仅仅是有题目中函数的操作,C语言中没有队列,需要自己实现。
我这里就不放出来了,我用的是循环队列。循环队列我之前在数据结构章节中有实现,同时也有源码。
循环队列链接

typedef struct
{
    Queue Q1;
    Queue Q2;
}MyStack;


MyStack* myStackCreate()
{
    MyStack* stack = (MyStack*)malloc(sizeof(MyStack));
    QueueInit(&stack -> Q1);
    QueueInit(&stack -> Q2);
    
    return stack;
}

void myStackPush(MyStack* obj, int x)
{
    //那一个队列不为空 往那一个里面去插入数据
    if(!QueueEmpty(obj -> Q1))
    {
        QueuePush(&obj -> Q1,x);
    }
    else
    {
        QueuePush(&obj -> Q2,x);
    }
}

int myStackPop(MyStack* obj)
{
    //假设队列1 为空的
    Queue* empty = &obj -> Q1;
    Queue* noempty = &obj -> Q2;

    //假设错了 该队列不为空 那就交换一下
    if(!QueueEmpty(*empty))
    {
        empty = &obj -> Q2;
        noempty = &obj -> Q1;
    }

    //将该队列中的最后一个前的数据全部导入到空队列中去
    while(abs((noempty->front) - (noempty->rear)) > 1)
    {
        QueuePush(empty,QueueGetTop(*noempty));
        QueuePop(noempty);
    }

    int top = QueueGetTop(*noempty);
    QueuePop(noempty);
    return top;
}

int myStackTop(MyStack* obj)
{
    if(!QueueEmpty(obj -> Q1))
    {
        return obj -> Q1.data[obj->Q1.rear-1];
    }
    else
    {
        return obj -> Q2.data[obj->Q2.rear-1];
    }
}

bool myStackEmpty(MyStack* obj)
{
    //两个队列都为空
    return QueueEmpty(obj -> Q1) == QueueEmpty(obj -> Q2) ? true : false; 
}

void myStackFree(MyStack* obj)
{
    free(obj);
}

3.用栈实现队列

在这里插入图片描述
额……………………

  • 它和上题一样,也得使用两个栈出来
  • 这两个栈,有着不一样的意义,
  • 第一个栈用于存放入队列,第二个栈用来出队列。
  • 看下图:最终从S2出栈不久成了 1 2 3 4 了吗?
    在这里插入图片描述
  • 入队列,就是往第一个栈里面放东西,
  • 出队列,就需要判断,如果当前的栈为空,那么就将第一个栈导入进去,如果不为空,那么直接访问栈顶元素就好了。

下面是代码,栈在这里的代码也没有放出来,思路就是这么一个思路,自己动手实现一下栈还是可以的。

typedef struct
{
    Stack S1;
    Stack S2;
}MyQueue;


MyQueue* myQueueCreate()
{
    MyQueue* Q = (MyQueue*)malloc(sizeof(MyQueue));
    StackInit(&Q -> S1);
    StackInit(&Q -> S2);

    return Q;
}

void myQueuePush(MyQueue* obj, int x)
{
    StackPush(&obj -> S1,x);
}

int myQueuePop(MyQueue* obj)
{

    int top = myQueuePeek(obj);
    StackPop(&obj -> S2);

    return top;
}

int myQueuePeek(MyQueue* obj)
{
    //如果第二个栈中没有元素
    if(StackEmpty(obj -> S2))
    {
        //将s1中的元素push入s2中去
        while(!StackEmpty(obj -> S1))
        {
            StackPush(&obj -> S2,StackTop(obj -> S1));
            StackPop(&obj -> S1);
        }
    }


    int top = StackTop(obj -> S2);
    return top;
}

bool myQueueEmpty(MyQueue* obj)
{
    return StackEmpty(obj -> S1) && StackEmpty(obj -> S2) ? true : false; 
}
 
void myQueueFree(MyQueue* obj)
{
    free(obj);
}

4.棒球比赛

在这里插入图片描述
这个题目中用到了一个atoi的函数。

  • 构造一个栈,然后对所给的字符进行判断,如果是数字的话就入栈
  • 如果不是数字的话,做其相对应的操作即可。
  • 最后将栈中所有数字的和加在一起就好了
int calPoints(char** operations, int operationsSize)
{
    int* stack = (int*)malloc(sizeof(int) * (operationsSize+1));
    int top = 0,gettop,i;
    int ans = 0;
    for (i = 0; i < operationsSize; i++)
    {
        if(operations[i][0] == 'C')
        {
            stack[top--];
        }
        else if(operations[i][0] == 'D')
        {
            gettop = stack[top];
            stack[++top] = gettop * 2;
        }
        else if(operations[i][0] == '+')
        {
            int num1 = stack[top];
            int num2 = stack[top-1];
            stack[++top] = num1 + num2;
        }
        else    //分数
        {
            stack[++top] = atoi(operations[i]);
        }
    }

    while(top != 0) 
    {
        gettop = stack[top--];
        ans += gettop;
    }

    return ans;
}

5.比较含退格的字符串

在这里插入图片描述
这道题可以使用双指针来解决,但是在本文中,我使用栈来解决

  • 构造两个栈出来。
  • 分别对两个字符串进行遍历,如果遇到退格符就出栈,
  • 没遇到就入栈
  • 最后一边出栈一遍比较即可。
bool backspaceCompare(char* s, char* t)
{
    int lens = strlen(s),lent = strlen(t);
    char* ss = (int*)malloc(sizeof(int) * (lens+1));
    char* st = (char*)malloc(sizeof(char) * (lent+1));
    int tops = 0,topt = 0;
    char gettops,gettopt;
    int i;
    for (i = 0; i < lens; i++)
    {
        if(s[i] == '#' && tops == 0)
        {
            continue;
        }


        //入栈与出栈
        if(s[i] == '#')
        {
            ss[tops--];
        }
        else
        {
            ss[++tops] = s[i];
        }
    }


     for (i = 0; i < lent; i++)
    {
        if(t[i] == '#' && topt == 0)
        {
            continue;
        }

        //入栈与出栈
        if(t[i] == '#') 
        {
            st[topt--];
        }
        else
        {
           st[++topt] = t[i];
        }
    }

    while(tops != 0 && topt !=0)
    {
        gettops = ss[tops--];
        gettopt = st[topt--];
        if(gettops != gettopt)
        {
            return false;
        }

    }


    return tops == topt ? true : false;
}

6.删除字符串中的所有相邻重复项

在这里插入图片描述
这道题双指针和栈都可以解决,下面我用栈解决的。

  • 去遍历一遍字符串,如果栈为空,就将当前的元素入栈,
  • 如果栈不为空,那么去判断当前元素和栈顶元素是否相同,
  • 如果相同,出栈,否则入栈。
  • 最后将这个栈返回即可。
char* removeDuplicates(char* s)
{
    int i = 0, len = strlen(s);
    //栈
    char* stack = (char*)malloc(sizeof(char) * (len + 1));
    int top = 0;
    char gettop;

    //先将第一个数据入栈

    while (s[i] != '\0')
    {
        if (top == 0)
        {
            stack[++top] = s[i++];
            continue;
        }
        gettop = stack[top];

        if (gettop == s[i])
        {
            top--;
        }
        else
        {
            stack[++top] = s[i];
        }
        i++;
    }
    stack[++top] = '\0';
    return (stack+1);
}

7.商品折扣后的最终价格

在这里插入图片描述
这道题可以用暴力双for,直接做出,也可以用单调栈来解答,一下是单调栈的方式

  • 需要构造一个哈希表,这个哈希表是当前下标,所对应的该打多少折的下标。
  • 额。。。。有点抽象,看图。
    在这里插入图片描述

为什么不直接在钱下面存放需要减去的前,因为有的测试用例,它可能出现两件商品价格一样,那时候打折就会发生冲突。

  • 介绍完哈希表后,就要构造一个单调栈出来了,
  • 单调栈其实在刷数组的时候用到过,在下面这道题中有过,我前面数组中也有关于单调栈的解析,不过这次是构造一个单调减的栈,只需要改一下符号即可。

在这里插入图片描述

已下是代码:



/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* finalPrices(int* prices, int pricesSize, int* returnSize)
{
    int* stack = (int*)malloc(sizeof(int) * (pricesSize+1));
    int top = 0,gettop,i;
    *returnSize = 0;
    int hash[501] = {0};
    int* ans = (int*)malloc(sizeof(int) * pricesSize);

    for (i = 0; i < pricesSize; i++)
    {
        //栈不为空,且外边的数据比栈顶的小
        while(top != 0 && prices[i] <= prices[stack[top]])
        {
            gettop = stack[top--];
            hash[gettop] = i;       //记录其下标吧

        }
        stack[++top] = i;
    }

    for (i = 0; i < 10; i++)
    {
        printf("%d ",hash[i]);
    }

    for (i = 0; i < pricesSize; i++)
    {
        if(hash[i] != 0)
        {
            ans[(*returnSize)++] = prices[i] - prices[hash[i]];
        }
        else
        {
            ans[(*returnSize)++] = prices[i] - 0;
        }
    }

    return ans;
}

8.整理字符串

在这里插入图片描述

  • 遍历字符串,挨个入栈,入栈的同时去判断题目中所给的那两个条件,
  • 去决定入栈还是出栈,最后将该栈返回即可

代码有点长,其中确实有的许多地方可以简写,使其更整洁,但是思路就是这样子。
题解中还有一块代码,非常简洁,思路还是这个思路。


char * makeGood(char * s)
{
    int i,len = strlen(s);
    char* stack = (char*)malloc(sizeof(char)* (len + 2));
    int top = 0;
    char gettop;

    for (i = 0; i < len; i++)
    {   
        //栈不为空才可以操作。
        if(top != 0)
        {
            gettop = stack[top];
            //如果当前是小写字母,后面是大写字母
            if((gettop >= 'a' && gettop <= 'z') && (s[i] >= 'A' && s[i] <= 'Z'))
            {
                char tmp = tolower(s[i]);
                if(tmp == gettop)
                {
                    //出栈
                    top--;
                    continue;
                }
            }
            if((gettop >= 'A' && gettop <= 'Z') && (s[i] >= 'a' && s[i] <= 'z'))
            {
                char tmp = toupper(s[i]);
                if(tmp == gettop)
                {
                    //出栈
                    top--;
                    continue;
                }
            }

            stack[++top] = s[i];
            
        }
        else
        {
            stack[++top] = s[i];
        }
    }

    stack[++top] = '\0';

    return (stack+1);
}

char * makeGood(char * s){
    int n = strlen(s);
    char *buf = malloc(n + 1);
    int top = 0;
    buf[top] = s[0];
    for (int i = 1; s[i]; i++){
        if (top >= 0 && (buf[top] - 'A' == s[i] - 'a' || buf[top] - 'a' == s[i] - 'A')){
            top--;
        }
        else{
            buf[++top] = s[i];
        }
    }
    buf[++top] = 0;
    return buf;
}

9.文件夹操作日志搜集器

在这里插入图片描述
还是利用栈实现,不过我下面就不用栈了,因为它只要返回几次,所以利用栈的top即可

int minOperations(char** logs, int logsSize)
{
    int top = 0,i;

    for (i = 0; i < logsSize; i++)
    {
        //不出栈,也不入栈
        if(strcmp(logs[i],"./") == 0)
        {
            continue;
        }
        else if(strcmp(logs[i],"../") == 0)
        {
            //栈不为空才去 出栈
            if(top != 0)
            {
                top--;
            }
        }
        else
        {
            top++;
        }
    }
    
    return top; 
}

10.括号的最大深度

在这里插入图片描述
因为题目中所给的字符串中括号的格式一定是正确的,那么直接统计出有多少个左括号就好。

  • 遇到左括号入栈,更新最值
  • 遇到右括号出栈。
int Max(int x,int y)
{
    return x > y ? x : y;
}

int maxDepth(char* s)
{
    int top = 0,ans = 0,len = strlen(s),i;

    for (i = 0; i < len; i++)
    {
        //左括号入栈,同时更新最多的次数
        if(s[i] == '(')
        {
            top++;
            ans = Max(top,ans);
        }
        else if (s[i] == ')')   //出栈
        {
            top--;
        }
    }

    return ans;
}

11. 无法吃午餐的学生数量

在这里插入图片描述
那么长的题目读不懂的话,看一下例子就懂了。
这道题,有说法。

  • 先统计出喜欢吃各自的人数。
  • 然后去遍历那一个三明治数组,所对应的各自减去,唯一要注意的就是,那边人数先为空的话,循环就可以结束了,
  • 直接看代码可能有些奇妙,
  • 想一想,如果队列中始终一有一个人喜欢吃方的,即使他在最后一个,是不是经过许多次的出队列,入队列,他最终都会上去的。
int countStudents(int* students, int studentsSize, int* sandwiches, int sandwichesSize)
{
    int s1 = 0;
    for (int i = 0; i < studentsSize; i++)
    {
        s1 += students[i];
    }
    int s0 = studentsSize - s1;
    for (int i = 0; i < sandwichesSize; i++)
    {
        if (sandwiches[i] == 0 && s0 > 0)
        {
            s0--;
        } else if (sandwiches[i] == 1 && s1 > 0)
        {
            s1--;
        } else
        {
            break;
        }
    }
    return s0 + s1;
}

12.删除字串后的字符串最小长度

在这里插入图片描述
这道题和前面的好多题几乎是一样的,不一样的只是判断条件而已

int minLength(char * s)
{
    int i,len = strlen(s);
    char* stack = (char*)malloc(sizeof(char) * (len + 1));
    int top = 0;

    for (i = 0; i < len; i++)
    {
        //栈不为空去进行判断操作
        if(top != 0 && ((stack[top] == 'A' && s[i] == 'B') || (stack[top] == 'C' && s[i] == 'D')))
        {
            top--;
        }
        else
        {
            stack[++top] = s[i];
        }
    }

    return top;
}

13.图书整理

在这里插入图片描述
他这道题就是让咱实现一个队列,题目中说两个书车,既然又出现在栈里面,那应该是让咱用两个栈实现一个队列,就像前面的那一道题一样,这里我就直接实现一个队列过了的。


#define MAX_SIZE 250


typedef struct
{
    int data[MAX_SIZE];
    int front;
    int rear;
} CQueue;


CQueue* cQueueCreate()
{
    CQueue* Q = (CQueue*)malloc(sizeof(CQueue));
    Q -> front = Q -> rear = 0;

    return Q;
}

void cQueueAppendTail(CQueue* obj, int value)
{
    if((obj -> rear + 1) % MAX_SIZE == obj -> front)
    {
        printf("队列满了\n");
        exit(-1);
    }

    obj -> data[(obj -> rear)++] = value;

    if(obj -> rear >= MAX_SIZE)
    {
        obj -> rear = 0;
    }
}


bool QueueEmpty(CQueue* obj)
{
    return obj -> front == obj -> rear ? true : false;
}

int cQueueDeleteHead(CQueue* obj)
{
    if(QueueEmpty(obj))
    {
        return -1;
    }

    int tmp = obj -> data[(obj -> front)++];
    if(obj -> front >= MAX_SIZE)
    {
        obj -> front = 0;
    }

    return tmp;
}

void cQueueFree(CQueue* obj)
{
    free(obj);
}

/**
 * Your CQueue struct will be instantiated and called as such:
 * CQueue* obj = cQueueCreate();
 * cQueueAppendTail(obj, value);
 
 * int param_2 = cQueueDeleteHead(obj);
 
 * cQueueFree(obj);
*/

14.最小栈

在这里插入图片描述
这道题是构造栈,它这个最小栈的意思就是可以用O(1)的方式去直接找到栈中最小的,如果直接遍历得出结果,还叫什么最小栈。

  • 需要两个栈,,一个正常存放栈中每一个元素,
  • 另一个则存放越来越小的数,
  • 如果要删除的数据,和最小栈中栈顶的数据一样,那么就一起出栈
  • 否者只出正常栈中的数据

在这里插入图片描述

#define MAX_SIZE 10000


typedef struct
{
    int data[MAX_SIZE];
    int top;
    int mindata[MAX_SIZE];    //记录下来
    int mintop;
} MinStack;

/** initialize your data structure here. */

MinStack* minStackCreate()
{
    MinStack* s = (MinStack*)malloc(sizeof(MinStack));
    s -> top = s -> mintop = 0;

    return s;
}

void minStackPush(MinStack* obj, int x)
{
    if(obj -> top + 1 >= MAX_SIZE)
    {
        printf("栈满了\n");
        exit(-1);
    }

    obj -> data[++(obj -> top)] = x;
    

    if(obj -> mintop == 0)
    {
        obj -> mindata[++(obj -> mintop)] = x;
    }
    else if (obj -> mindata[obj -> mintop] >= x)
    {
        obj -> mindata[++(obj -> mintop)] = x;
    }


}

void minStackPop(MinStack* obj)
{
    if(obj -> data[obj -> top] == obj -> mindata[obj -> mintop])
    {
        obj -> mintop--;;
    }

    obj -> top--;
}

int minStackTop(MinStack* obj)
{
    return obj -> data[obj -> top];   
}

int minStackGetMin(MinStack* obj)
{
    return obj -> mindata[obj -> mintop]; 
}

void minStackFree(MinStack* obj)
{
    free(obj);    
}

/**
 * Your MinStack struct will be instantiated and called as such:
 * MinStack* obj = minStackCreate();
 * minStackPush(obj, x);
 
 * minStackPop(obj);
 
 * int param_3 = minStackTop(obj);
 
 * int param_4 = minStackGetMin(obj);
 
 * minStackFree(obj);
*/

15 .三合一
在这里插入图片描述
额。。。。。这道题的意思就是将一个数组,分成三段然后去实现栈。
在这里插入图片描述


typedef struct {
    int top[3];     //栈顶指针,注意要分成三个
    int size;       //单个栈的总长度,需要保存下来出入栈时使用
    int* data;      //只是用一个数组进行数据存储,长度设为三倍的栈总长
} TripleInOne;


TripleInOne* tripleInOneCreate(int stackSize) {
    TripleInOne* obj=(TripleInOne*)malloc(sizeof(TripleInOne));
    obj->data=(int*)calloc(3*stackSize,sizeof(int));
    obj->size=stackSize;
    obj->top[0]=-1;
    obj->top[1]=-1;
    obj->top[2]=-1;
    return obj;
}

void tripleInOnePush(TripleInOne* obj, int stackNum, int value) {
    //判断当前栈指针是否到达尾部
    if(obj->top[stackNum] == obj->size - 1){

    }else{
        //这里注意,要把指针后移单独拿出来,因为后续入栈定向是使用的代数式进行
        obj->top[stackNum]++;
        obj->data[obj->top[stackNum] + stackNum * obj->size] = value;
    }
}

int tripleInOnePop(TripleInOne* obj, int stackNum) {
    if(obj->top[stackNum] == -1){
        return -1;
    }else{
        //这里注意,要把指针前移单独拿出来,因为出栈定向是使用的代数式进行
        int value = obj->data[obj->top[stackNum] + stackNum * obj->size];
        obj->top[stackNum]--;
        return value;
    }
}


int tripleInOnePeek(TripleInOne* obj, int stackNum) {
    //根据题意当前栈为空时返回-1
    if(obj->top[stackNum] == -1){
        return -1;
    }
    //如果栈不为空,则从数组中取出当前栈顶元素返回
    return obj->data[obj->top[stackNum] + stackNum * obj->size];
}

bool tripleInOneIsEmpty(TripleInOne* obj, int stackNum) {
    //判断当前栈顶指针是否为-1
    return obj->top[stackNum] == -1;
}

void tripleInOneFree(TripleInOne* obj) {
    free(obj->data);
    free(obj);
}

15. 删除最外层的括号

在这里插入图片描述
这和上面的括号的最大深度有关联的,括号同时也是规范的。

char* removeOuterParentheses(char* s)
{
    int i,len = strlen(s);
    char* ans = (char*)malloc(sizeof(char) * (len+1));
    int top = 0;
    int index = 0;
    for (i = 0; i < len; i++)
    {
        if(s[i] == ')')
        {
            top--;
        }

        if(top > 0)
        {
            ans[index++] = s[i];
        }

        if(s[i] == '(')
        {
            top++;
        }
    }

    ans[index] = '\0';
    return ans;
}

结尾

上面就是leetcode上所有关于栈的简单题了,有好几个重复的,就没往上放,还有些二叉树的题,也没有放。

  • 11
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值