Leetcode 双周赛 31

5456. 在区间范围内统计奇数数目

Leetcode 双周赛 31_第1张图片
直接数就好了

class Solution:
    def countOdds(self, low: int, high: int) -> int:
        return (high-low)//2+1 if high&1 or low&1 else (high-low)//2

5457. 和为奇数的子数组数目

Leetcode 双周赛 31_第2张图片
说实话这题着实难为了我一下

'''
本质上是dp
以dp(i)表示以当前位结尾的和为奇数的子数组个数的话
dp(i)=dp(i-1) i位为偶数
dp(i)=sum(dp(k))+even even为从第i-1个奇数开始数的连续的偶数个数,k为i前第2j个奇数,j为整数,i为奇数
'''
class Solution:
    def numOfSubarrays(self, arr: List[int]) -> int:
        even=0
        ans=0
        d=0#因当前数字所产生的增量
        d1=0#因第1,3,5,7,9...个奇数所产生的增量和
        d2=0#因第2,4,6,8....个奇数所产生的增量和
        d1flag=1
        for ni in arr:
            if ni&1:
            #是奇数的情况,就考虑有1,3,5,7...个奇数的子数组
                if d1flag:
                    d1+=even+1
                    d=d1
                else:
                    d2+=even+1
                    d=d2
                d1flag^=1
                ans+=d
                even=0
            else:
            #是偶数只需考虑最靠近这个偶数最前面所有的奇数所产生的子数组
                even+=1
                ans+=d
        return ans%(10**9+7)

5458. 字符串的好分割数目

Leetcode 双周赛 31_第3张图片

class Solution:
    def numSplits(self, s: str) -> int:
        cnt1=[0 for _ in range(26)]
        cnt2=[0 for _ in range(26)]
        for ch in s:
            cnt2[ord(ch)-ord('a')]+=1
        ans=0
        for ch in s:
            cnt1[ord(ch)-ord('a')]+=1
            cnt2[ord(ch)-ord('a')]-=1
            sum1=sum2=0
            for i in range(26):
                if cnt1[i]>0:
                    sum1+=1
                if cnt2[i]>0:
                    sum2+=1
            if sum1==sum2:
                ans+=1
        return ans

5459. 形成目标数组的子数组最少增加次数

Leetcode 双周赛 31_第4张图片

class Solution:
    def minNumberOperations(self, target: List[int]) -> int:
        ans=0
        target=[0]+target
        for i in range(1,len(target)):
            if target[i]>=target[i-1]:
                ans+=target[i]-target[i-1]
        return ans

你可能感兴趣的:(Leetcode刷题,leetcode,数据结构,算法,动态规划)