1.2 LeetCode总结(线性表)_栈队列类

本文深入探讨了多种编程技巧和算法实现,包括用栈实现队列的双栈法,有效括号字符串的判断,基本计算器的计算逻辑,以及二叉树的层次遍历等。通过具体实例讲解了算法设计思想和C语言实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

编程总结

每每刷完一道题后,其思想和精妙之处没有地方记录,本篇博客用以记录刷题过程中的遇到的算法和技巧

232. 用栈实现队列

在这里插入图片描述

要点就是,先要有栈的数据结构及其实现,然后用两个栈,一个作in stack,一个作out stack来实现队列的先入先出:
a. 进队列,都默认进到 in stack里;
b. 查队列首元素,要求先入先出,那就得先将 in stack 的数据都放到 out stack 里去,这时 out stack 里的top元素就是队列要出的元素;
c. 出队列时,先判断 out stack是否为空,为空则in2out搬运,否则,直接出out stack的top即可;

// 1. 栈数据结构的实现
typedef struct {
	int *stk;
	int stkSize;
	int stkCapacity;
} Stack;
Stack *stackCreate(int capacity)
{
	Stack *ret = (Stack *)malloc(sizeof(Stack));
	ret->stk   = (int *)malloc(sizeof(int) * capacity);
	ret->stkSize = 0;
	ret->stkCapacity = capacity;
	return ret;
}
void stackPush(Stack *obj, int x)
{
	obj->stk[obj->stkSize++] = x;
}
void stackPop(Stack *obj)
{
	obj->stkSize--;
}
int stackTop(Stack *obj)
{
	return obj->stk[obj->stkSize - 1];
}
bool stackEmpty(Stack *obj)
{
	return obj->stkSize == 0; // size为0,则满足条件为空,返回1
}
void stackFree(Stack *obj)
{
	free(obj->stk);
}
---------------------------------------------------------
// 2. 队列数据结构的实现
typedef struct {
	Stack *inStack;
	Stack *outStack;
} MyQueue;
// in stack -> out stack.
void in2out(MyQueue *obj) {
	while (!stackEmpty(obj->inStack)) {
		stackPush(obj->outStack, stackTop(obj->inStack));
		stackPop(obj->inStack);
	}
}
// 1. 建立两个栈
MyQueue *myQueueCreate() {
	MyQueue *ret  = (MyQueue *)malloc(sizeof(MyQueue));
	ret->inStack  = stackCreate(100);
	ret->outStack = stackCreate(100);
	return ret;
}
// 2. 进入到 in栈
void myQueuePush(MyQueue *obj, int x) {
	stackPush(obj->inStack, x);      // 直接入栈即可
}
// 3. 出队列的队首元素为 out栈的栈顶元素
int myQueuePop(MyQueue *obj) {
	if (stackEmpty(obj->outStack)) { // 这三行是精髓的部分,判断out是否为空,若不为空,则直接出栈Top,若为空,则将in stack搬运过来
		in2out(obj);
	}
	int x = stackTop(obj->outStack);
	stackPop(obj->outStack);
	return x;
}
// 4. 返回队列开头的元素,先判断如果out栈为空,就更新in的元素过去,最后返回out栈的栈顶元素
int myQueuePeek(MyQueue *obj) {
	if (stackEmpty(obj->outStack)) {
		in2out(obj);
	}
	return stackTop(obj->outStack);
}
bool myQueueEmpty(MyQueue *obj) {
	return stackEmpty(obj->inStack) && stackEmpty(obj->outStack);
}
void myQueueFree(MyQueue *obj) {
	stackFree(obj->inStack);
	stackFree(obj->outStack);
}

020.有效括号

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串

思路:将字符串都判断如果是左括号(‘(’,‘[’,‘{’,‘(’)都进行入栈,遇到其他括号符号则:1)取出栈顶元素,2)同时将栈顶元素的match括号匹配上,3)然后Pop栈顶元素和match元素进行比对,如果一致继续循环判断,否则退出,直到遍历完所有的字符串长度。
在这里插入图片描述

a. 遇到左括号放入栈顶
b. 遇到右括号,取出栈顶的左括号并判断它们是否是相同类型的括号; 如果不是相同的类型,或者栈中并没有左括号,那么字符串无效,返回 False(先入栈也行,最后判断栈里是否都清空了)

C语言实现一个栈往往较为复杂,多数解题是通过一个数组来模拟栈
下面给出用数组模拟上述算法的代码:

bool isTrue(char a, char b)
{
	if ((a == '(' && b == ')') || (a == '[' && b == ']') || (a == '{' && b == '}')) {
		return true;
	}
	return false;
}
bool isValid(const char *s)
{
	char str[10001] = {0};  // 定义一个数组当栈
	int top = -1;
	int i = 0;
	int len = strlen(s);
	if (len == 0) {
		return false;
	}
	// 出现奇数个时,一定为false.
	if (len % 2 == 1) {
		return false;
	}
	str[++top] = s[i];
	i++;
	while (i < len) {
		// 如果栈顶元素和字符匹配上了,则栈顶元素出栈
		if (top >= 0 && (isTrue(str[top], s[i]) == true)) { // 注意判断top < 0 时的传值, 此时str[top]无效
			top--;
		} else {
			str[++top] = s[i]; // 将字符入栈
		}
		i++;
	}
	if (top == -1) { // 栈内无元素了
		return true;
	} else {
		return false;
	}
}

顺带提一句在LeetCode平台的 False== 0; True == 1;在这里插入图片描述

678. 有效的括号字符串

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

此题是上一题的变种,手法类似,但处理起来有个星号的出现有点变化
手法1: 准备两个栈,一个存括号,一个存星号

  1. 星号变成右括号的情况:当左括号栈空时,从星号栈取来匹配右括号;(其实这里按理说也要判断下星号的下标在右括号之前)
  2. 星号变成左括号的情况:为了将每个左括号匹配,需要将星号看成右括号,且每个左括号必须出现在其匹配的星号之前,这里需要对下标进行判断;
#define STACK_SIZE 101
bool checkValidString(char *s)
{
	int stack1[STACK_SIZE] = {0}; // 存左括号
	int stack2[STACK_SIZE] = {0}; // 存星号
	int len = strlen(s);
	int i = 0;
	int top1 = 0;
	int top2 = 0;

	i = 0;
	while (i < len) {
		if (s[i] == '(') {
			stack1[top1] = i; // 下标存储下来
			top1++;
		}
		else if (s[i] == ')') {
			// 手法1:如果左括号栈不为空,则从左括号栈弹出栈顶元素;
			if (top1 > 0) {
				top1--;
			} else if (top1 == 0 && top2 > 0) { // 手法2:如果左括号栈为空且星号栈不为空,则从星号栈弹出栈顶元素;
				top2--;
			}
			else { // 手法3:如果左括号栈和星号栈都为空,则没有字符可以和当前的右括号匹配,返回 false
				return false;
			}
		}
		else if (s[i] == '*') {
			stack2[top2] = i;
			top2++;
		}
		i++;
	}
	i = 0;
	// 手法4:当两个栈都不为空时,每次从左括号栈和星号栈分别弹出栈顶元素
	// 对应左括号下标和星号下标,判断是否可以匹配,匹配的条件是左括号下标小于星号下标,如果左括号下标大于星号下标则返回 false。
	if (top2 != 0 && top1 != 0) {
		while (top1 > 0 && top2 > 0) {
			top1--;
			top2--;
			if (stack1[top1] > stack2[top2]) { // *要出现在(的右边,要求stack1[top1] < stack2[top2],否则为false.
				return false;
			}
		}
	}
	if (top1 == 0) {
		return true;
	}

	return false;
}

224.基本计算器

s有: 数字、‘+’、‘-’、‘(’、‘)’、和 ’ ’

实现一个基本的计算器来计算一个简单的字符串表达式的值。
字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格
一个运算符栈opors,一个运算数栈opands。

括号内的计算优先级最高。
碰到’(‘,‘(‘入opors栈。
碰到’)’,opors栈中栈顶到’(‘的运算符都要计算出来。 这表示括号内的表达式结束了,然后, ‘(‘ 出栈。
碰到’+”-‘, opors栈中栈顶到’(‘的运算符都要计算出来。 这是左结合性导致的。然后 ‘+”-‘ 入栈。
碰到数字,提取出整数,然后入opands栈。

int calculate(char *s) {
    int n = strlen(s);
    int ops[n], top = 0;
    int sign = 1;
    ops[top++] = sign;

    int ret = 0;
    int i = 0;
    while (i < n) {
        if (s[i] == ' ') {
            i++;
        } else if (s[i] == '+') {
            sign = ops[top - 1];
            i++;
        } else if (s[i] == '-') {
            sign = -ops[top - 1];
            i++;
        } else if (s[i] == '(') {
            ops[top++] = sign;
            i++;
        } else if (s[i] == ')') {
            top--;
            i++;
        } else {
            long num = 0;
            while (i < n && s[i] >= '0' && s[i] <= '9') {
                num = num * 10 + s[i] - '0';
                i++;
            }
            ret += sign * num;
        }
    }
    return ret;
}

227. 基本计算器 II

在这里插入图片描述

int calculate(char* s) {
    int n = strlen(s);
    int stk[n], top = 0;
    char preSign = '+';
    int num = 0;
    for (int i = 0; i < n; ++i) {
        if (isdigit(s[i])) {
            num = num * 10 + (int)(s[i] - '0');
        }
        if (!isdigit(s[i]) && s[i] != ' ' || i == n - 1) {
            switch (preSign) {
                case '+':
                    stk[top++] = num;
                    break;
                case '-':
                    stk[top++] = -num;
                    break;
                case '*':
                    stk[top - 1] *= num;
                    break;
                default:
                    stk[top - 1] /= num;
            }
            preSign = s[i];
            num = 0;
        }
    }
    int ret = 0;
    for (int i = 0; i < top; i++) {
        ret += stk[i];
    }
    return ret;
}

队列的典型应用:广度优先遍历
有两种通用的遍历树的策略:

1.深度优先搜索(DFS)
在这个策略中,我们采用深度作为优先级,以便从跟开始一直到达某个确定的叶子,然后再返回根到达另一个分支。
深度优先搜索策略又可以根据根节点、左孩子和右孩子的相对顺序被细分为先序遍历,中序遍历和后序遍历。

2.宽度优先搜索(BFS)
我们按照高度顺序一层一层的访问整棵树,高层次的节点将会比低层次的节点先被访问到。

102. 二叉树的层次遍历

给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。
在这里插入图片描述
利用二叉树的,先序遍历,根左右
这里需要注意的是最后是通过二维数组存放结果,对于指针的指针的处理需要注意,并且有树深度(returnSize)返回。

void helper(struct TreeNode* root, int **result, int *ColumnSizes, int i, int *maxh) {
	if (root == NULL) { // 递归终止条件
		return ;
	}
	result[i][ColumnSizes[i]] = root->val;   // 二叉树的前序遍历
	ColumnSizes[i]++;    // ColumnSize[i] 存放当前二维数组的列元素
	if (i + 1 > *maxh) { // 更新深度,由于 i+1 为深度,传值给 *maxh 为深度
		*maxh = i + 1;
	}
	helper(root->left, result, ColumnSizes, i + 1, maxh);  // i + 1 表示层次加1
	helper(root->right, result, ColumnSizes, i + 1, maxh); // maxh 表示 树的深度
}

int **levelOrder(struct TreeNode *root, int *returnSize, int **returnColumnSizes) {
	int **result = (int **)malloc(sizeof(int *) * MaxSize); // 二维数组,结果存放处, malloc行空间
	int i;

	for (i = 0; i < MaxSize; i++) {  // malloc列空间
		result[i] = (int *)malloc(sizeof(int) * MaxSize);
	}
	*returnColumnSizes = (int *)malloc(MaxSize * sizeof(int));
	memset(*returnColumnSizes, 0, MaxSize * sizeof(int));
	*returnSize = 0;    // 二维数组里行元素个数,也就是树的深度
	if (root == NULL) { // 异常判断
		return NULL;
	}
	helper(root, result, *returnColumnSizes, 0, returnSize);
	return result;
}

二叉树的层次遍历使用的更多的是利用队列的性质实现BFS,广度优先遍历:
下面还有队列的C语言实现。

#define MAX_QUEUE 10000

struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
 };
 
struct Queue
{
    int front; // 队头删除
    int rear;  // 队尾新增
    int size;
	struct TreeNode *array[MAX_QUEUE]; // 指针数组
};
void QueueInit(struct Queue *queue)
{
	memset(queue, 0, sizeof(*queue));
}
int QueueEmpty(struct Queue *queue)
{
    return (queue->size == 0);
}
void QueuePush(struct Queue *queue, struct TreeNode *node)
{
	queue->array[queue->rear] = node; // 往队尾增加一个元素
	queue->rear++;
	printf("Queue Push:queue->rear val %d\n", node->val);
    queue->size++;
}
int QueuePop(struct Queue *queue, int *data)
{
    if (QueueEmpty(queue)) {
       return 0;
    }
	printf("QueuePop\n");
	queue->front = (queue->front + 1);
	queue->size--;

	return 1;
}
void QueueDestroy(struct Queue* queue)
{
     queue->front = 0;
	 queue->rear = 0;
	 queue->size = 0;
	 free(queue->array);
	 free(queue);
}
struct TreeNode *QueueFront(struct Queue *q)
{
    if (q->size == 0)
        return NULL;
	printf("q->front val %d\n", q->array[q->front]->val);
    return q->array[q->front];
}

int **levelOrder(struct TreeNode *root, int *returnSize, int **returnColumnSizes)
{
	*returnSize = 0;
    *returnColumnSizes = 0;
	if (root == NULL) {
		return NULL;
	}
	int layer = 0;
	int data = 0;
    int **res = (int **)malloc(MAX_QUEUE * sizeof(int *));
    struct Queue *q = (struct Queue *)malloc(sizeof(struct Queue));
	QueueInit(q);
	*returnColumnSizes = (int *)malloc(MAX_QUEUE * sizeof(int)); 

    QueuePush(q, root);      // 插入root头结点
    while (!QueueEmpty(q)) { // 依次入队头结点/左右节点,然后利用队列性质先进先出队列
        int curNum = q->size;
        int *array = (int *)malloc(sizeof(int) * curNum);
        (*returnColumnSizes)[layer] = curNum; // returnColumnSizes 记录一个数组,数组元素是记录结果每一行的元素个数
		printf("--current size curNum-- %d\n", curNum);
        for (int i = 0; i < curNum; i++) {
            struct TreeNode *node = QueueFront(q); // 获取队头节点
            if (node) {
                array[i] = node->val;              // 获取每一行的结果
				printf("-----node->val %d-----\n\n",node->val);
                if (node->left) QueuePush(q, node->left);   // 左节点入队
                if (node->right) QueuePush(q, node->right); // 右节点入队
            }
            QueuePop(q, &data);// 队头节点出队列
        }
        res[layer++] = array;           // res 是结果存放的二维数组,array是每一行结果存放的一维数组
		printf("layer is %d\n", layer); // layer 是记录这个二维数组的行数,即深度
		free(array);
    }
    *returnSize = layer;
    free(q);
    return res;
}

98. 验证二叉搜索树

给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
在这里插入图片描述

bool isValid(struct TreeNode *root, long min ,long max) {
	if (root == NULL) {
		return 1; // 递归终止条件
	}
	if (min >= root->val) { //根节点必须大于min
		return false;
	}
	if (max <= root->val) {  //根节点必须小于max
		return false;
	}

	return isValid(root->left, min, root->val) && isValid(root->right, root->val, max);
}
bool isValidBST(struct TreeNode *root) {
	long min = -2147483649;  // 需要注意由于题目的 val 为int型,所以会有用例覆盖到 int的最值(-2147483649 - 2147483647),所以需要将min/max超过这个范围
	long max = 2147483649;   // 否则,如果出现一个根节点为min,将会直接判断false出去,但一个根节点的结果应该是true

	return isValid(root, min, max);
}

225.使用队列实现栈的下列操作

push(x) – 元素 x 入栈
pop() – 移除栈顶元素
top() – 获取栈顶元素
empty() – 返回栈是否为空
考虑到队列是一种 FIFO 的数据结构,最后入队的元素应该在最后被出队。因此我们需要维护另外一个队列 q2,这个队列用作临时存储 q1 中出队的元素。q2 中最后入队的元素将作为新的栈顶元素。接着将 q1 中最后剩下的元素出队。我们通过把 q1 和 q2 互相交换的方式来避免把 q2 中的元素往 q1 中拷贝

typedef struct SqQueue {
    int front;
    int rear;
    int dataLen;
    int data[1024];
} SqQueue_t;

// 初始化队列
SqQueue_t *SqQueueCreate(int dataLen) {
    SqQueue_t *queue = (SqQueue_t *)malloc(sizeof(SqQueue_t) + sizeof(int) * dataLen);
    queue->front = 0;
	queue->rear = 0;
    queue->dataLen = dataLen;

    return queue;
}

void SqQueueDestroy(SqQueue_t *queue) {
    free(queue);
}

int SqQueueFull(SqQueue_t *queue) {
    return (queue->front == (queue->rear + 1) % queue->dataLen);
}

int SqQueueEmpty(SqQueue_t *queue) {
    return (queue->front == queue->rear);
}

int SqQueuePush(SqQueue_t *queue, int data) {
    if (SqQueueFull(queue)){
        return -1;
	}
	// 将数据放置到队尾
    queue->data[queue->rear++] = data;  
	printf("Push:queue->rear is %d, data is %d\n", queue->rear, data);

    return 0;
}

int SqQueuePop(SqQueue_t *queue, int *data) {
    if (SqQueueEmpty(queue)) {
        return -1;
	}
	// 先进先出,按队头顺序出队列
    *data = queue->data[queue->front++];
	printf("Pop:queue->front is %d, data is %d\n", queue->front, *data);

    return 0;
}

/*---------------------两个队列实现栈---------------------*/
typedef struct {
    SqQueue_t *qA;
    SqQueue_t *qB;
} MyStack;

/** Initialize your data structure here. */
MyStack *myStackCreate() {
    MyStack *stack = (MyStack *)malloc(sizeof(MyStack));
    stack->qA = SqQueueCreate(20);
    stack->qB = SqQueueCreate(20);

    return stack;
}

/** Returns whether the stack is empty. */
bool myStackEmpty(MyStack *obj) {
    return (SqQueueEmpty(obj->qA) && SqQueueEmpty(obj->qB));
}

/** Returns whether the stack is empty. */
bool myStackFull(MyStack *obj) {
    return (SqQueueFull(obj->qA) || SqQueueFull(obj->qB));
}

/** Push element x onto stack. */
void myStackPush(MyStack *obj, int x) {
    if (myStackFull(obj))
        return;

    SqQueue_t *enQueue = NULL;
    if (!SqQueueEmpty(obj->qA)) {
        enQueue = obj->qA;
    } else {
        enQueue = obj->qB;
    }
    SqQueuePush(enQueue, x);
}

/** Removes the element on top of the stack and returns that element. */
int myStackPop(MyStack *obj) {
    if (myStackEmpty(obj)) {
        return -1;
	}
	int data;

    SqQueue_t *enQueue = NULL;
    SqQueue_t *deQueue = NULL;
    SqQueue_t *tmpQueue = NULL;

    if (!SqQueueEmpty(obj->qA)) {
        deQueue = obj->qA;  // qA A队列出数据
        enQueue = obj->qB;  // qB B队列收数据
    } else {
        deQueue = obj->qB;
        enQueue = obj->qA;
    }

    while (deQueue->rear != deQueue->front) {
		printf("\n");
        SqQueuePop(deQueue, &data);     // 队列1出数据,队列2收数据
        if (!SqQueueEmpty(deQueue)) {   // 队列1出完最后一个元素,队列2不接收,直接作为最后一个输出,它就是栈的Top元素
            SqQueuePush(enQueue, data);
        }
    }
	printf("rear is %d, front is %d\n", deQueue->rear, deQueue->front);

    return data;
}

/** Get the top element. */
int myStackTop(MyStack *obj) {
    if (myStackEmpty(obj)) {
        return -1;
	}

    SqQueue_t *enQueue = NULL;
    SqQueue_t *deQueue = NULL;
    int data;

	// 交换deQueue 和 enQueue
    if (!SqQueueEmpty(obj->qA)) {
        deQueue = obj->qA;
        enQueue = obj->qB;
    } else {
        deQueue = obj->qB;
        enQueue = obj->qA;
    }

    while (deQueue->rear != deQueue->front) {
        SqQueuePop(deQueue, &data);
        SqQueuePush(enQueue, data);
    }

    return data;
}

void myStackFree(MyStack *obj) {
    SqQueueDestroy(obj->qA);
    SqQueueDestroy(obj->qB);

    free(obj);
}

int main() 
{
	MyStack *stack = myStackCreate();
	myStackPush(stack, 1);
	myStackPush(stack, 2);
	myStackPush(stack, 3);
	myStackPush(stack, 4);
	printf("Pop element is %d\n", myStackPop(stack));

	return 0;
}

出栈时,队列A会先逐一拷贝元素至另一个队列B,直到最后一个元素Pop出去;
下次出栈时,就反过来,此队列A已经空了,作为存储队列,队列B Push进队列A,直到最后一个元素Pop出去。
在这里插入图片描述

typedef struct Stack {
	int data[MAX_SIZE];
	int top;
	int min;
} MinStack; // 为Stack 起了一个别名,后续可以直接使用MinStack来定义变量

MinStack *minStackCreate() {
	 MinStack *obj = (MinStack *)malloc(sizeof(MinStack));
	if (obj) {
		obj->top = -1;
		obj->min = INT_MAX;
		return obj;
	}
	return NULL;
}

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() —— 检索栈中的最小元素。
输入:
[“MinStack”,“push”,“push”,“push”,“getMin”,“pop”,“top”,“getMin”]
[[],[-2],[0],[-3],[],[],[],[]]
输出:
[null,null,null,null,-3,null,0,-2]
解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.

#include <stdio.h>
#include <string.h>
#include <stdlib.h> 
#include <math.h>

#define MAX_SIZE 100

typedef struct Stack {
	int data[MAX_SIZE];
	int top;
	int min;  // 保留一个最小值
} MinStack;

MinStack *minStackCreate() {
	 MinStack *obj = (MinStack *)malloc(sizeof(MinStack));
	if (obj) {
		obj->top = -1;
		obj->min = INT_MAX;
		return obj;
	}
	return NULL;
}

void minStackPush(MinStack *obj, int x) {
	if (obj->top == MAX_SIZE - 1) { // 达到最大值
		return;
	}

	obj->data[++obj->top] = x;
	obj->min = fmin(obj->min, x);  // 保存最小值 
}

void minStackPop(MinStack *obj) {
	int i = 0;

	if (obj->top < 0) {
		obj->min = INT_MAX;
		return;
	}

	obj->top--;
	obj->min = INT_MAX;
	// top后这里为什么需要重新找 min 点
	for (i = 0; i <= obj->top; i++) {
		obj->min = fmin(obj->min, obj->data[i]);
	}
}

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

int minStackGetMin(MinStack *obj) {
	return obj->min;               // 返回最小值
}

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

682. 棒球比赛

在这里插入图片描述

int calPoints(char **ops, int opsSize) 
{
	int num[10001] = {0};
	int top = -1;
	int i = 0;
	int result = 0;
	int res = 0;

	if (opsSize == 0) {
		return 0;
	}
	while (i < opsSize) {
		if (ops[i][0] == 'C') {
			top--; // 出栈,前一次得分无效
		}
		else if (ops[i][0] == 'D') {
			result = 2 * num[top];
			num[++top] = result;
		}
		else if (ops[i][0] == '+') {
			if (top > 0) {
				result = num[top] + num[top - 1];
				num[++top] = result;
			}
		} 
		else { // 由于分数可能出现超过2位的,所以我们在这统一使用 atoi 函数转
			num[++top] = atoi(ops[i]); 
		}
		i++;
	}
	for (i = 0; i <= top; i++) {
		res = res + num[i];
	}

	return res;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值