2055. 蜡烛之间的盘子 【每日一题】

本文介绍了如何通过观察字符串中'>'和'*'的组合来计算蜡烛之间的盘子数,通过预处理计算前后|的下标和对应盘子数,展示了两种避免超时的方法:正则表达式匹配和暴力模拟。

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

2055. 蜡烛之间的盘子

思路

          我们要怎么才能得到中间的盘子数呢,显然有个烟雾弹是两个蜡烛,其实我们只要知道这个区间[start,end]从前往后的第一个| 前面的盘子数 和从后往前的第一个| 之前的盘子数就行了,在蜡烛中间的盘子数等于后者减前者,只要想到这儿就基本代码出来了,

          问题是怎么才能想到这儿呢,我没想到,我是看题解的,看得多了,我觉得我下次就想得到这儿了

          问题就变成了确定strat 往后的第一个| 的下标x,和end往前的最近的|下标y, 以及每个下标对应的该位置之前的盘子数

          三个问题,挨个解决

代码

class Solution:
    def platesBetweenCandles(self, s: str, queries: List[List[int]]) -> List[int]:
        n = len(s)
        ans = []
        """
        我们要怎么才能得到中间的盘子数呢,显然有个烟雾弹是两个蜡烛,其实我们只要知道这个区间[start,end]从前往后的第一个| 前面的盘子数
        和从后往前的第一个| 之前的盘子数就行了,在蜡烛中间的盘子数等于后者减前者,只要想到这儿就基本代码出来了,

        问题是怎么才能想到这儿呢,我没想到,我是看题解的,看得多了,我觉得我下次就想得到这儿了
        
        问题就变成了确定strat 往后的第一个| 的下标x,和end往前的最近的|下标y, 以及每个下标对应的该位置之前的盘子数

        三个问题,挨个解决
        """
        sums=0

        # 每个下标对应的该位置之前的盘子数
        presum = [0]*n
        for i in range(n):
            if s[i]=="*":
                sums += 1
            presum[i] = sums
        
        left = [0]*n  # 计算每个位置左边最近|的下标索引  其实就是往后往前的
        index = -1
        for i in range(n):
            if s[i]=="|":
                index = i
            left[i]=index
        
        right = [0]*n  # 计算每个位置右边最近|的下标索引  其实就是从前往后的,在右边嘛
        index = -1
        for i in range(n-1,-1,-1):
            if s[i]=="|":
                index = i
            right[i] = index
        
        for start,end in queries:
            x = right[start]   # 起始点右边最近的|位置
            y = left[end]      # 终点前面(左边)最近的|位置
            if x==-1 or y==-1 or x>=y:
                ans.append(0)
            else:
                ans.append(presum[y]-presum[x])

        return ans

两种超时的

正则

class Solution:
    def platesBetweenCandles(self, s: str, queries: List[List[int]]) -> List[int]:
        n = len(s)
        ans = []

        # 正则超时
        for start,end in queries:
            substr = s[start:end+1]
            # 用零宽断言来匹配
            replace_str = re.sub(r"(?<=\|)(.)+?(?=\|)",r"",substr)
            # 我先将关键字A替换成AA,来保证找到所有的匹配情况,在进行后续的替换处理,这种方法不用学,是当时不懂零宽断言写的
            # replace_str1 = re.sub(r"[|]",r"||",substr)
            # replace_str2 = re.sub(r"[|][*]+[|]",r"||",replace_str1)

            ans.append(len(replace_str1)-len(replace_str2))
            
        return ans

零宽断言演示的看这儿 字符串提取两个关键字中间的所有字符

暴力

class Solution:
    def platesBetweenCandles(self, s: str, queries: List[List[int]]) -> List[int]:
        n = len(s)
        ans = []
        
        # 暴力模拟也超时
        for start,end in queries:
            # print(start,end,s)
            substr = s[start:end+1]
            length = len(substr)
            st=-1
            e=length
            for i in range(length):
                if substr[i] == "|":
                    st = i
                    break
            for i in range(length-1,-1,-1):
                if substr[i]=="|":
                    e = i
                    break
            if st==-1 or e ==length:
                ans.append(0)
                continue
            realstr = substr[st:e+1]
            count = realstr.count("|")
            ans.append(e+1-st-count)

        return ans
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

中南自动化学院至渝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值