leetcode:856. 括号的分数

题目来源

题目描述

在这里插入图片描述

class Solution {
public:
    int scoreOfParentheses(string s) {

    }
};

题目解析

思路

在这里插入图片描述

class Solution {
public:
    int scoreOfParentheses(string pstr) {
        std::stack<int> stk;
        for (int i = 0; i < pstr.size(); ++i) {
            if(pstr[i] == '('){
                stk.push(0);   //遇到左括号入栈,用0模拟
            }else{
                auto top = stk.top();     //栈顶为0即栈顶为左括号,此时为()的情况,得1分   
                if(stk.top() == 0){
                    stk.pop();
                    stk.push(1);
                }else{  //栈顶不为左括号即为(ABC)的情况,得分为(A+B+C)*2
                    int score = 0;
                    while (stk.top() != 0){
                        score += stk.top();
                        stk.pop();
                    }
                    stk.pop();
                    stk.push(score * 2);
                }
            }
        }

        int score = 0;
        while (!stk.empty() ){
            score += stk.top();
            stk.pop();
        }
        return score;
    }
};

思路

  1. 首先要明确一个重点:这里边真正有作用的就是"()“这对括号,所有的值的来源都是由”()"经过了加和或者相乘得来的

  2. 不妨直接做一个替换:既然"()“的值为1,我们就直接利用replace函数把”()“替换成"1”,那我们就得到了 “(())“变为”(1)”; “()()“变为"11”;”(()(()))“变为”(1(1))"

  3. 分析一下替换后的内容,“(1(1))” 直观上是(1+1×2)×2=1×2+1×2×2 (加法分配律) 如此一来,直接看当前位置的1的前面有多少个"(“就可以知道×几个2了,如第一个"1"前有一个,第二个"1"前有两个。同理呢,遇见”)“我们就要除以2了:(1)(1)=1×2+1×2 第二个"1"前有两个”(“和一个”)“,会抵消一个,就剩一个”(",所以×2。

综上,我们遇见"(“就直接*2好了,遇见”("就直接/2,遇见"1"就赶紧加上去。

class Solution:
    def scoreOfParentheses(self, s: str) -> int:
        s=s.replace('()','1')
        nums=1
        res=0
        for i in s:
            if i == "(":
                nums*=2
            if i == ")":
                nums/=2
            if i == "1":
                res+=nums
        return int(res)

递归

思路

  • 先找出每一个最外层的括号,再对其中间的整体部分调用递归

实现

class Solution {
public:
    int scoreOfParentheses(string pstr) {
        int res = 0, n = pstr.size();
        for (int i = 0; i < n; ++i) {
            if(pstr[i] == ')'){
                continue;
            }
            
            //找部分合法的括号字符串: 使用一个计数器,遇到左括号,计数器自增1,反之右括号计数器自减1,那么当计数器为0的时候,就是一个合法的字符串了
            int pos = i + 1, cnt = 1;
            while (cnt != 0){  // (
                (pstr[pos++] == '(') ? ++cnt : --cnt;
            }
            // (((())))(
            // i       p   
            // 对除去最外层的括号的中间内容调用递归 ((()))
            int cur = scoreOfParentheses(pstr.substr(i + 1, pos - i - 2));
            res += max(2 * cur, 1);
            i = pos - 1;
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值