滑动窗口

76. 最小覆盖子串

3. 无重复字符的最长子串

1004. 最大连续1的个数 III

1052. 爱生气的书店老板

面试题59 - II. 队列的最大值

1438. 绝对差不超过限制的最长连续子数组

1423. 可获得的最大点数

76. 最小覆盖子串

给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。

示例:

输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"
说明:

如果 S 中不存这样的子串,则返回空字符串 ""。
如果 S 中存在这样的子串,我们保证它是唯一的答案。

1.构建一个滑动窗口,左右指针怎么移动?右指针移动:当窗口内的内容不满足条件 左指针:当窗口内的指针满足条件

class Solution:
    def minWindow(self, s: 'str', t: 'str') -> 'str':
        t=collections.Counter(t)
        lookup=collections.defaultdict(int)
        minLen=float('inf')
        res=""
        l=r=0
        while r<len(s):
            lookup[s[r]]+=1
            r+=1
            while all(map(lambda x:lookup[x]>=t[x],t.keys())):
                if r-l<minLen:
                    res=s[l:r]
                    minLen=r-l
                lookup[s[l]]-=1
                l+=1
        return res

class Solution:
    def minWindow(self, s: 'str', t: 'str') -> 'str':
        lookup=collections.defaultdict(int)
        for i in t:lookup[i]+=1
        count=len(t)
        l=r=0
        min_len=float('inf')
        res=""
        while r<len(s):
            if lookup[s[r]]>0:count-=1
            lookup[s[r]]-=1
            r+=1
            while count==0:
                if min_len>r-l:
                    min_len=r-l
                    res=s[l:r]
                if lookup[s[l]]==0:count+=1
                lookup[s[l]]+=1
                l+=1
        return res




3. 无重复字符的最长子串

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

1.双指针+hash

class Solution:
    def lengthOfLongestSubstring(self, s):
        lookup=collections.defaultdict(int)
        res=0
        l=r=0
        count=0
        while r<len(s):
            if lookup[s[r]]>0:count+=1#这个字符前面出现过
            lookup[s[r]]+=1
            r+=1
            while count>0:
                if lookup[s[l]]>1:count-=1
                lookup[s[l]]-=1
                l+=1
            res=max(res,r-l)
        return res


class Solution(object):
    def lengthOfLongestSubstring(self, s):
        if not s:return 0
        l=r=0
        res=0
        h={}
        while r<len(s):
            if s[r] in h:
                l=max(l,h[s[r]])
            res=max(res,r-l+1)
            h[s[r]]=r+1
            r+=1
        return res

1004. 最大连续1的个数 III

给定一个由若干 0 和 1 组成的数组 A,我们最多可以将 K 个值从 0 变成 1 。

返回仅包含 1 的最长(连续)子数组的长度。

 

示例 1:

输入:A = [1,1,1,0,0,0,1,1,1,1,0], K = 2
输出:6
解释: 
[1,1,1,0,0,1,1,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 6。

1.直接暴力o(n³)

2.sum优化成前缀和暴力o(n²)

3.滑动窗口,右指针一直右走,左指针当窗口内的0的个数>k时右走

class Solution:
    def longestOnes(self, A: List[int], K: int) -> int:
        if K>=A.count(0):return len(A)
        res=0
        for i in range(len(A)):
            for j in range(i+1,len(A)):
                if j-i+1-sum(A[i:j+1])==K:
                    res=max(res,sum(A[i:j+1])+K)
        return res

class Solution:
    def longestOnes(self, A: List[int], K: int) -> int:
        if K>=A.count(0):return len(A)
        res=0
        pre=[0 for _ in range(len(A))]
        pre[0]=A[0]
        for i in range(1,len(A)):
            pre[i]=pre[i-1]+A[i]
        for i in range(len(A)):
            for j in range(i+1,len(A)):
                if i-1>=0:sum_=pre[j]-pre[i-1]
                else:sum_=pre[j]
                if j-i+1-sum_==K:
                    res=max(res,sum_+K)
        return res

class Solution:
    def longestOnes(self, A: List[int], K: int) -> int:
        if K>=len(A):return len(A)
        l=r=0
        res=0
        count=0
        while r<len(A):
            if A[r]==0:count+=1
            while count>K:
                if A[l]==0:count-=1
                l+=1
            res=max(res,r-l+1)
            r+=1
        return res

1052. 爱生气的书店老板

今天,书店老板有一家店打算试营业 customers.length 分钟。每分钟都有一些顾客(customers[i])会进入书店,所有这些顾客都会在那一分钟结束后离开。

在某些时候,书店老板会生气。 如果书店老板在第 i 分钟生气,那么 grumpy[i] = 1,否则 grumpy[i] = 0。 当书店老板生气时,那一分钟的顾客就会不满意,不生气则他们是满意的。

书店老板知道一个秘密技巧,能抑制自己的情绪,可以让自己连续 X 分钟不生气,但却只能使用一次。

请你返回这一天营业下来,最多有多少客户能够感到满意的数量。

1.暴力直接枚举grumpy数组连续的x个数为0的情况

2.滑动窗口

class Solution:
    def maxSatisfied(self, customers: List[int], grumpy: List[int], X: int) -> int:
        res=0
        def func(index):
            ans=0
            for i in range(len(customers)):
                if grumpy[i]==0 or index<=i<=index+X-1:
                    ans+=customers[i]
            return ans

        for i in range(len(grumpy)-X+1):
            res=max(res,func(i))
        return res

class Solution:
    def maxSatisfied(self, customers: List[int], grumpy: List[int], X: int) -> int:
        res1=0
        for i in range(len(customers)):
            if grumpy[i]==0:
                res1+=customers[i]
                customers[i]=0
        l=0
        r=X-1
        tmp_sum=sum(customers[:X])
        res2=tmp_sum
        while r<len(customers):
            r+=1
            if r>len(customers)-1:break
            tmp_sum+=customers[r]
            tmp_sum-=customers[l]
            l+=1
            res2=max(res2,tmp_sum)
            
        return res1+res2


面试题59 - II. 队列的最大值

请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。

若队列为空,pop_front 和 max_value 需要返回 -1

示例 1:

输入: 
["MaxQueue","push_back","push_back","max_value","pop_front","max_value"]
[[],[1],[2],[],[],[]]
输出: [null,null,null,2,1,2]

1.用普通队列实现,max_value用暴力获取其值

2.用一个辅助队列

class MaxQueue:

    def __init__(self):
        self.q=collections.deque()


    def max_value(self) -> int:
        return max(self.q) if self.q else -1
        


    def push_back(self, value: int) -> None:
        self.q.append(value)


    def pop_front(self) -> int:
        return self.q.popleft() if self.q else -1

class MaxQueue(object):

    def __init__(self):
        self.q=collections.deque()
        self.q_keep=collections.deque()


    def max_value(self):
        return self.q_keep[0] if self.q_keep else -1
  

    def push_back(self, value):
        self.q.append(value)
        while self.q_keep and self.q_keep[-1]<value:
            self.q_keep.pop()
        self.q_keep.append(value)
 
        
    def pop_front(self):
        if not self.q:return -1
        res=self.q.popleft()
        if res==self.q_keep[0]:self.q_keep.popleft()
        return res


1438. 绝对差不超过限制的最长连续子数组

给你一个整数数组 nums ,和一个表示限制的整数 limit,请你返回最长连续子数组的长度,该子数组中的任意两个元素之间的绝对差必须小于或者等于 limit 。

如果不存在满足条件的子数组,则返回 0 。

1.很好的题,滑动窗口(一般求子串,子区间问题可以考虑),滑动窗口问题需要考虑2个指针怎么移动,r指针可以走的话一直往右走,左指针当窗口内容不满足条件时往左走,这里的条件就是窗口内的max_value-min_value<=limit,这里就涉及到另一个知识点,怎么用o(1)的时间获得当前区间的最值?单调队列!,维护2个单调队列!

class Solution:
    def longestSubarray(self, nums: List[int], limit: int) -> int:
        q_max=[]
        q_min=[]
        res=0
        l=r=0
        while r<len(nums):
            while q_max and nums[r]>nums[q_max[-1]]:
                q_max.pop()
            q_max.append(r)
            while q_min and nums[r]<nums[q_min[-1]]:
                q_min.pop()
            q_min.append(r)
            while q_min and q_max and nums[q_max[0]]-nums[q_min[0]]>limit:
                if q_max[0]<=l:q_max.pop(0)
                if q_min[0]<=l:q_min.pop(0)
                l+=1
            res=max(res,r-l+1)
            r+=1
        return res

1423. 可获得的最大点数

几张卡牌 排成一行,每张卡牌都有一个对应的点数。点数由整数数组 cardPoints 给出。

每次行动,你可以从行的开头或者末尾拿一张卡牌,最终你必须正好拿 k 张卡牌。

你的点数就是你拿到手中的所有卡牌的点数之和。

给你一个整数数组 cardPoints 和整数 k,请你返回可以获得的最大点数。

输入:cardPoints = [1,2,3,4,5,6,1], k = 3
输出:12
解释:第一次行动,不管拿哪张牌,你的点数总是 1 。但是,先拿最右边的卡牌将会最大化你的可获得点数。最优策略是拿右边的三张牌,最终点数为 1 + 6 + 5 = 12 。

1.贪心+前缀和

2.dfs直接左右2种情况搜索,超时

3.滑动窗口

class Solution:
    def maxScore(self, cardPoints: List[int], k: int) -> int:
        n=len(cardPoints)
        left=[0 for _ in range(n+1)]
        right=[0 for _ in range(n+1)]
        for i in range(n):
            left[i+1]=left[i]+cardPoints[i]
            right[i+1]=right[i]+cardPoints[n-i-1]
        res=0
        l=r=0
        u=k
        for i in range(k):
            if left[l+u]-left[l]>right[r+u]-right[r]:
                res+=cardPoints[l]
                print("left",cardPoints[l])
                l+=1
            else:
                res+=cardPoints[n-r-1]
                print("right",cardPoints[r])
                r+=1
            u-=1
        return res
        
class Solution:
    def maxScore(self, cardPoints: List[int], k: int) -> int:
        if k==len(cardPoints):return sum(cardPoints)
        def dfs(l,r,k):
            if k==1:return max(cardPoints[l],cardPoints[r])
            return max(dfs(l+1,r,k-1)+cardPoints[l],dfs(l,r-1,k-1)+cardPoints[r])
        return dfs(0,len(cardPoints)-1,k)

 

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 创作都市 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读