代码随想录day11| 20. 有效的括号 、 1047. 删除字符串中的所有相邻重复项 、 150. 逆波兰表达式求值

题目链接: 20. 有效的括号 

思路:这道题中出现三种会出现匹配的情况

第一种是左括号多了

——当遍历完字符串后栈里面还有元素

第二种是左右不匹配

——字符与栈顶元素不匹配

第三种是右括号多了

——栈的长度为零了,还有字符串中右方向括号还没有遍历完

代码实现

int notMatch(char par, char* stack, int stackTop) {
    switch(par) {
        case ']':
            return stack[stackTop - 1] != '[';
        case ')':
            return stack[stackTop - 1] != '(';
        case '}':
            return stack[stackTop - 1] != '{';
    }
    return 0;
}

bool isValid(char * s){
    int strLen = strlen(s);
    //开辟栈空间
    char stack[5000];
    int stackTop = 0;

    //遍历字符串
    int i;
    for(i = 0; i < strLen; i++) {
        //取出当前下标所对应字符
        char tempChar = s[i];
        //若当前字符为左括号,则入栈
        if(tempChar == '(' || tempChar == '[' || tempChar == '{')
            stack[stackTop++] = tempChar;
        //若当前字符为右括号,且栈中无元素或右括号与栈顶元素不符,返回False
        else if(stackTop == 0 || notMatch(tempChar, stack, stackTop))
            return 0;
        //当前字符与栈顶元素为一对括号,将栈顶元素出栈
        else
            stackTop--;
    }
    //若栈中有元素,返回False。若没有元素(stackTop为0),返回True
    return !stackTop;
}

notMatch中为什么栈顶元素要减1

——因为代码中使用了后加加的操作,所以说stackTop其实是指向了下一位元素了

题目链接:047. 删除字符串中的所有相邻重复项 

方法一(栈)

char* removeDuplicates(char* s) {
    int strlength = strlen(s);

    char* stack = (char*)malloc(sizeof(char)*strlength + 1);
    int stackTop = 0;

    int index = 0;
    while(index < strlength){
        char letter = s[index++];

        if(stackTop > 0 && letter == stack[stackTop - 1] ){
            stackTop--;
        }
        else 
            stack[stackTop++] = letter;
        
        stack[stackTop] = '\0';
      
    }
      return stack;
    }

方法二(双指针)

这道题可以看作是移除元素的题目,与数组不一样的地方是字符串以'\0'结尾的,

代码实现

char* removeDuplicates(char* s) {
    int fast = 0;
    int slow = 0; 
    
    int strlength = strlen(s);
    while(fast < strlength)
    {
        char letter = s[slow] = s[fast++];
        if(slow > 0 && letter == s[slow - 1])
            slow--;
        else
            slow++;
        
    }
    s[slow] = '\0';
    return s;
}

为什么要写 char letter = s[slow] = s[fast++];

——这里其实已经隐藏了删除的操作,假如说前面的没有重复的元素,那么由于后加加的操作,只会将原本的元素复制,假如前面是有出现的重复的元素,那么新的元素就给旧的覆盖,然后实现删除的操作

题目链接:150. 逆波兰表达式求值

代码实现

int evalRPN(char** tokens, int tokensSize) {
   long long stack[MAX_TOKENS];  
    int top = -1; 
    for (int i = 0; i < tokensSize; i++) {  
        if (strcmp(tokens[i], "+") == 0 || strcmp(tokens[i], "-") == 0 ||  
            strcmp(tokens[i], "*") == 0 || strcmp(tokens[i], "/") == 0) {  
            long long num1 = stack[top--]; 
            long long num2 = stack[top--]; 
  
            if (strcmp(tokens[i], "+") == 0) stack[++top] = num2 + num1;  
            if (strcmp(tokens[i], "-") == 0) stack[++top] = num2 - num1;  
            if (strcmp(tokens[i], "*") == 0) stack[++top] = num2 * num1;  
            if (strcmp(tokens[i], "/") == 0) stack[++top] = num2 / num1; 
        } else {  
            stack[++top] = atoi(tokens[i]); 
        }  
    }  
  
 
    return stack[top];  
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值