Leetcode刷题-不定长窗口求最短/最小

209

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        n = len(nums)
        res = n + 1
        left = 0
        now = 0
        for i in range(n):
            now += nums[i]
            
            while now - nums[left] >= target:
                now -= nums[left]
                left += 1
            
            if now >= target:
                res = min(res, i - left + 1)
        
        if res < n + 1:
            return res
        return 0

2904

class Solution:
    def shortestBeautifulSubstring(self, s: str, k: int) -> str:
        left = 0
        res = ""
        n = len(s) + 2
        now = ""
        w = 0
        for right in range(len(s)):
            if s[right] == "1":
                w += 1
            if w < k:
                continue
            while s[left] != "1":
                left += 1
            if n > right - left + 1:
                now = s[left: right + 1]
                n = right - left + 1
            elif n == right - left + 1 and now > s[left: right + 1]:
                now = s[left: right + 1]
            left += 1
            w -= 1
        return now
            

1234

class Solution:
    def balancedString(self, s: str) -> int:
        n = len(s)
        res = n
        n = n // 4
        dic = defaultdict(int)
        for i in s:
            dic[i] += 1
        if dic["Q"] == dic["W"] == dic["E"] == dic["R"] == n:
            return 0
        left = 0
        for right in range(len(s)):
            dic[s[right]] -= 1
            while max(dic.values()) <= n:
                res = min(right - left + 1, res)
                dic[s[left]] += 1
                left += 1
        return res

2875

使用变长滑动窗口,并将target转化为target % sum(nums),这样就可以大大减少循环次数,如果不做处理就会超时。

class Solution:
    def minSizeSubarray(self, nums: List[int], target: int) -> int:
        n = len(nums)
        a = sum(nums)
        p = target // a
        m = 2 * n
        left = 0
        res = inf
        now = 0
        target = target % a
        for right in range(m):
            now += nums[right % n]

            while now > target:
                now -= nums[left % n]
                left += 1
            if now == target:
                res = min(res, right - left + 1)
        if res < inf:
            return res + p * n
        else:
            return -1

79

class Solution:
    def minWindow(self, s: str, t: str) -> str:
        cntT = Counter(t)
        cnt = Counter()
        ansl = -1
        ansr = len(s)
        left = 0
        for i,c in enumerate(s):
            cnt[c] += 1

            while cnt >= cntT:
                if i - left < ansr - ansl:
                    ansl = left
                    ansr = i
                cnt[s[left]] -= 1
                left += 1

        if ansl < 0:
            return ""
        else:
            return s[ansl: ansr + 1]
            

632

class Solution:
    def smallestRange(self, nums: List[List[int]]) -> List[int]:
        pairs = sorted((x, i) for (i, arr) in enumerate(nums) for x in arr)
        emt = len(nums)
        left = 0
        ansr = inf
        ansl = -inf
        cnt = defaultdict(int)
        print(pairs)
        for i, x in pairs:
            if cnt[x] == 0:
                emt -= 1
            cnt[x] += 1
            while emt == 0:
                l,t = pairs[left]
                if i - l < ansr - ansl:
                    ansr = i
                    ansl = l
                cnt[t] -= 1
                if cnt[t] == 0:
                    emt += 1
                left += 1
        return [ansl,ansr]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

YoloMari

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

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

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

打赏作者

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

抵扣说明:

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

余额充值