[英雄星球七月集训LeetCode解题日报] 第8日 前缀和

日报

  • 今天的题纠结了半天!

题目

一、 1894. 找到需要补充粉笔的学生编号

链接: 1894. 找到需要补充粉笔的学生编号

1. 题目描述

在这里插入图片描述

2. 思路分析
  • 设学生一轮总共要s根粉笔,显然k中超过s倍数的数是没用的,我们先把k对s取余:k%=s
  • 然后我们求出学生的前缀和,在前缀和里二分找到k落的位置即可。
3. 代码实现
class Solution:
    def chalkReplacer(self, chalk: List[int], k: int) -> int:
        n = len(chalk)
        presum = list(accumulate(chalk))
        k %= presum[-1]
        return bisect_right(presum,k)%n         

二、2256. 最小平均差

链接: 2256. 最小平均差

1. 题目描述

在这里插入图片描述

2. 思路分析
  • 按题意模拟即可。
  • 由于要求连续区间和,因此我们做前缀和优化。
3. 代码实现
class Solution:
    def minimumAverageDifference(self, nums: List[int]) -> int:
        n = len(nums)
        presum = list(accumulate(nums))
        ans = 0
        min_avg = inf
        for i in range(n):
            avg = abs(presum[i]//(i+1) - ((presum[n-1]-presum[i])//(n-i-1) if i < n-1 else 0))
            if avg < min_avg:
                ans = i 
                min_avg =avg
        return ans

三、1737. 满足三条件之一需改变的最少字符数

链接: 1737. 满足三条件之一需改变的最少字符数

1. 题目描述

在这里插入图片描述

2. 思路分析
  • 按题意先计算方案三初始化ans:找两个串中最多的字符,其它字符都变成它。
  • 然后分别计算:
    • 把a中字符串都变成字符i,b中小于等i的字符都变成i+1以上的字符,消耗的步骤;
    • 把b中字符串都变成字符i,a中小于等i的字符都变成i+1以上的字符,消耗的步骤;
    • 注意这个i<25,因为如果变成z,另个字符串都变成z+1是不存在的。
3. 代码实现
class Solution:
    def minCharacters(self, a: str, b: str) -> int:
        m,n = len(a),len(b)
        cnt = Counter(a)+Counter(b)
        _,c = cnt.most_common(1)[0]
        ans = m+n-c 
        
        arr1,arr2 = [0]*26,[0]*26
        for c in a:
            arr1[ord(c)-ord('a')] += 1
        for c in b:
            arr2[ord(c)-ord('a')] += 1
        presum1 = list(accumulate(arr1,initial =0))
        presum2 = list(accumulate(arr2,initial =0))
        # print(presum1,presum2)
        for i in range(26):
            if i<25:
                ans = min(ans, presum1[26]-presum1[i+1] + presum2[i+1])
                ans = min(ans, presum2[26]-presum2[i+1] + presum1[i+1])           
        return ans

四、2055. 蜡烛之间的盘子

链接: 2055. 蜡烛之间的盘子

1. 题目描述

在这里插入图片描述

2. 思路分析
  • 预处理把盘子变成1,蜡烛变成0,题目转化为查询区间内被0包围的1的数量,即区间求和。
  • 我们可以把每个蜡烛出现的位置整理成有序数组,然后二分的去找每个查询区间内最左边和最右边的蜡烛。
  • 也可以对每个位置预处理一个它左边、右边最近的蜡烛位置。
  • 这样对于每个查询[l,r],我们先计算这个查询l右边第一个蜡烛位置left,r左边第一蜡烛位置right,那么[left,right]内的盘子数量就是答案。
  • 由于是区间求和,用前缀和优化即可
3. 代码实现
class Solution:
    def platesBetweenCandles(self, s: str, queries: List[List[int]]) -> List[int]:        
        n = len(s)
        left,right = [n]*n, [n]*n
        l = -1
        for i in range(n):
            if s[i] == '|':
                l = i
            left[i] = l
        r = n
        for i in range(n-1,-1,-1):
            if s[i] == '|':
                r = i
            right[i] = r

        dish = list(accumulate([1 if c == '*' else 0 for c in s], initial=0))
       
        ans = []
        for l,r in queries:
            first = right[l]
            last = left[r]
            # print(first,last)
            if first >= last :
                ans.append(0)
            else:
                ans.append(dish[last+1] - dish[first])
        return ans            
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值