[LeetCode周赛复盘] 第 315 场周赛20221016

一、本周周赛总结

  • 前三题很水,T4突然很难。
  • T3没考虑0的情况wa一次。
  • T4写了个九十多行单调栈,很难搞,wa一次。
  • T1哈希表模拟
  • T2哈希表模拟
  • T3遍历模拟
  • T4滑窗
    在这里插入图片描述

二、 [Easy] 6204. 与对应负数同时存在的最大正整数

链接: 6204. 与对应负数同时存在的最大正整数

1. 题目描述

在这里插入图片描述

2. 思路分析

按题意模拟即可。

3. 代码实现

class Solution:
    def findMaxK(self, nums: List[int]) -> int:
        s = set(nums)
        ans = -1
        for v in nums:
            if v > 0 and -v in s:
                ans = max(ans,v)
        return ans

三、[Medium] 6205. 反转之后不同整数的数目

链接: 6205. 反转之后不同整数的数目

1. 题目描述

在这里插入图片描述

2. 思路分析

按题意模拟即可。

  • 由于是python 翻转时借用字符串更方便。

3. 代码实现

class Solution:
    def countDistinctIntegers(self, nums: List[int]) -> int:
        s = set(nums)
        for v in nums:
            x = int(str(v)[::-1])
            s.add(x)
        return len(s)

四、[Medium] 6219. 反转之后的数字和

链接: 6219. 反转之后的数字和

1. 题目描述

在这里插入图片描述

2. 思路分析

  • 按题意模拟。
  • 注意i的上界,如果不判断0,那么要取到num。

3. 代码实现

class Solution:
    def sumOfNumberAndReverse(self, num: int) -> bool:      
        if num == 0:
            return True
        for i in range(num):
            j = int(str(i)[::-1])
            if i + j == num:
                return True
        return False

五、[Hard] 6207. 统计定界子数组的数目

链接: 6207. 统计定界子数组的数目

1. 题目描述

在这里插入图片描述

2. 思路分析

  • 比赛时写了非常麻烦的单调栈(因为看到了区间最小最大)。
  • 实际上滑窗是比较简单的思路:
  • 数组中值不在[minK,maxK]区间内的数都是不能为答案做贡献的,这些点都用不了,因此这些点可以把数组分成很多段。
  • 在这些段之间计算区间数量即可。
  • 枚举区间右端点r,如何找左端点l的个数呢。
  • 需要当前段内存在minK和maxK即可,l最左能取到段左端,最右能取到上一个min和max的左边那个。

  • 这题也可以套板子二分,用线段树或者st都可以。
  • 枚举每个下标作为r,它左边的最大值和最小值具有单调性。

3. 代码实现

class Solution:
    def countSubarrays(self, nums: List[int], minK: int, maxK: int) -> int:
        n = len(nums)
        
        if minK == maxK:
            ans = 0
            f = [0]*n
            if nums[0] == minK:
                f[0] = 1
            for i in range(1,n):
                if nums[i] == minK:
                    f[i] = f[i-1]+1                
            
            return sum(f)
            
        ans = 0
        mn = -1 
        mx = -1
        q = deque()
        for r,v in enumerate(nums):
            if v<minK or v > maxK:
                mn = -1 
                mx = -1
                q.clear()
                continue        
            q.append(r)
            if v == minK:
                mn = r
            if v == maxK:
                mx = r
            if mn >=0 and mx >= 0:
                ans += min(mn,mx)-q[0] + 1

        return ans

单调栈做法

class Solution:
    def countSubarrays(self, nums: List[int], minK: int, maxK: int) -> int:
        n = len(nums)
        
        if minK == maxK:
            ans = 0
            f = [0]*n
            if nums[0] == minK:
                f[0] = 1
            for i in range(1,n):
                if nums[i] == minK:
                    f[i] = f[i-1]+1                
            
            return sum(f)
            
        st = []
        lmn = [-1]*n
        lmx = [-1]*n
        rmn = [n]*n
        rmx = [n]*n
        stmn = []
        stmx = []
        for i in range(n):
            v = nums[i]
            while stmn and nums[stmn[-1]] >= v:
                stmn.pop()
            if stmn:
                lmn[i] = stmn[-1]
            while stmx and nums[stmx[-1]] <= v:
                stmx.pop()
            if stmx:
                lmx[i] = stmx[-1]
            stmn.append(i)
            stmx.append(i)
        stmn = []
        stmx = []
        for i in range(n-1,-1,-1):
            v = nums[i]
            while stmn and nums[stmn[-1]] >= v:
                stmn.pop()
            if stmn:
                rmn[i] = stmn[-1]
            while stmx and nums[stmx[-1]] <= v:
                stmx.pop()
            if stmx:
                rmx[i] = stmx[-1]
            stmn.append(i)
            stmx.append(i)
                
        # print(list(zip(lmn,rmn)))
        # print(list(zip(lmx,rmx)     ) ) 
        ans = 0
        mn = []
        mx = []
        used = set()
        lll = 0
        for i in range(n):
            if nums[i] == minK:
                l,r = lmn[i]+1,rmn[i]-1                
                mn.append([i,l,r])                
                if  mx :   # 另一个
                    j,a,b = mx[-1]
                    if j not in used:
                        used.add(j)                    
                        if b>=l:   # 交集
                            ll = max(a,l,lll)
                            lll = j+1
                            rr = min(b,r)
                            x,y = i,j
                            if x>y:
                                x,y = y,x
                            if ll<=i<=rr and ll<=j<=rr:
                                ans += (x-ll+1)*(rr-y+1)  
            # print(nums[i],maxK)
            if nums[i] == maxK:                
                l,r = lmx[i]+1,rmx[i]-1
                mx.append([i,l,r])
                if  mn:
                    j,a,b = mn[-1]                    
                    if j not in used:
                        used.add(j)    
                        if b>=l:
                            ll = max(a,l,lll)
                            lll = j + 1
                            rr = min(b,r)
                            x,y = i,j
                            if x>y:
                                x,y = y,x
                            if ll<=i<=rr and ll<=j<=rr:
                                ans += (x-ll+1)*(rr-y+1) 
        # print(mn,mx)

        return ans
       
            
            

六、参考链接

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值