代码随想录训练营第11天|20.有效的括号、1047.删除字符串中的所以有相邻重复项、150.逆波兰表达式

目录

20.有效的括号

1.覆盖

2.栈

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

150.逆波兰表达式求值

atoi():将字符串转化为整型值

itoa():将整型值转化为字符串


20.有效的括号

题目链接:力扣

题目描述:给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。

1.覆盖

bool isValid(char * s){
    int n=strlen(s);
    if(n%2!=0)      return false;
    int slow=0;
    int fast=0;
    for(;fast<n;fast++){
        //串首出现右括号
        if(slow==0&&(s[fast]==')'||s[fast]==']'||s[fast]=='}')){
            return false;
        }
        //成功匹配
        if(s[fast]==')'&&s[slow-1]=='('||s[fast]==']'&&s[slow-1]=='['||s[fast]=='}'&&s[slow-1]=='{'){
            slow--;
        }else{
            //没匹配成功的覆盖字符串
            s[slow++]=s[fast];
        }
    }
    return slow==0;
}

        学了双指针之后就习惯于用fast和slow来代替之前的指针来做遍历,但是我之前的想法貌似更简洁,占用空间也更少。

bool isValid(char * s){
    if(strlen(s)%2!=0)  return false;
    int i=0;
    char *t=s;
    while(*t!='\0'){
        if(i==0&&(*t=='}'|| *t==')'|| *t==']'))     return false;
        if(*t==')'&&s[i-1]=='('||*t==']'&&s[i-1]=='['||*t=='}'&&s[i-1]=='{')
            i--;
        else{
            s[i++]=*t;
        }
        t++;
    }
    return i==0;
}

2.栈

栈来实现稍微有一点绕。

char pairs(char a) {
    if (a == '}') return '{';
    if (a == ']') return '[';
    if (a == ')') return '(';
    return '\0';
}
bool isValid(char * s){
    int n=strlen(s);
    if(n%2!=0)  return false;
    int top=-1;    //栈顶下标
    char box[n];    //顺序栈
    for(int i=0;i<n;i++){
        char c=pairs(s[i]);
        //出现右括号的情况
        if(c){
            //串首出现右括号以及栈顶不是与之匹配的左括号false
            if(top==-1||box[top]!=c){
                return false;
            }else{
                top--;
            }
        }
        //对应if:出现左括号一定压栈
        else{
            box[++top]=s[i];
        }
    }
    return top==-1?true:false;
}

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

题目链接:力扣

题目描述:给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。

在 S 上反复执行重复项删除操作,直到无法继续删除。

在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

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

150.逆波兰表达式求值

题目链接:力扣

题目描述:给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。

请你计算该表达式。返回一个表示表达式值的整数。

示例:

输入:tokens = ["4","13","5","/","+"]
输出:6
解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6

很明显用栈来解决(线性栈)

遇到运算符的时候POP俩个数字字符串,运算结果重新压回栈中,最终栈内的唯一元素就是表达式的结果。

//计算a与b运算的结果
int calculate(int num1,int num2,char *c){
    if(!strcmp(c,"+"))      return num1+num2;
    if(!strcmp(c,"-"))      return num1-num2;
    if(!strcmp(c,"*"))      return num1*num2;
    if(!strcmp(c,"/"))      return num1/num2;
    return 0;
}
int evalRPN(char ** tokens, int tokensSize){
    int stack[tokensSize];
    int top=0;
    for(int i=0;i<tokensSize;i++){
        //出现数字-入栈
        if(strcmp(tokens[i],"+")&&strcmp(tokens[i],"-")&&strcmp(tokens[i],"*")&&strcmp(tokens[i],"/")){
            stack[top++]=atoi(tokens[i]);
        //出现运算符-出栈
        }else{
            char *temp=tokens[i];
            int num2=stack[--top];
            int num1=stack[--top];
            stack[top++]=calculate(num1,num2,temp);
        }
    }
    return stack[0];
}

atoi():将字符串转化为整型值

朴实的我的实现:

int To_digit(char *s){
    int digit=0;
    for(int i=0;i<strlen(s);i++){
        digit=digit*10+s[i]-'0';
    }
    printf("%d\n",digit);
    return digit;
}

itoa():将整型值转化为字符串

朴实的我的实现:

#define Max_Size 10
char *To_string(int digit){
	char *ret=(char *)malloc(sizeof(char)*Max_Size);
	int index=0;
	//将数字各个位数拆解成字符逆序存入ret 
	while(digit){
		ret[index++]=(digit%10)+'0';
		digit/=10;
	}
	ret[index]='\0';
	int left=0;int right=index-1;
	char temp='\0';
	//逆置字符串 
	while(left<right){
        temp=ret[left];ret[left]=ret[right];ret[right]=temp;
        left++;right--;
    }
	return ret;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值