Leecode(3)

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

在这里插入图片描述直接通过遍历查找最长子串,因为是无重复字符,所以可以用set()

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        if not s: return 0
        n=len(s)
        ans=0
        for i in range(n):
            for j in range(i+1,n):
                if len(set(s[i:j]))!=j-i:
                    break
                
                ans=max(ans,j-i)
                
        return ans

使用滑动窗口(个人感觉还是双指针):
如果右指针的数重复,左指针右移一格
如果不重复,右指针右移一格,比较字符串长度和最大长度

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        if not s: return 0
        look = set()
        ans = 0
        n = len(s)
        i, j = 0, 0
        while j < n:
            while j < n and s[j] not in look:
                look.add(s[j])
                ans = max(ans, j - i + 1)
                j += 1
            else:
                look.remove(s[i])
                i += 1
        return ans

438. 找到字符串中所有字母异位词

在这里插入图片描述
滑动窗口就是双指针,右指针到p的长度时停下,如果窗口中字符串和p一样,就记录左指针的位置,否则左指针右移一位。

class Solution(object):
    def findAnagrams(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: List[int]
        """
        m=len(s)
        n=len(p)
        shad=[0]*26
        phad=[0]*26
        ans=[]
        i,j=0,0
        for char in p:
            phad[ord(char)-ord('a')]+=1
        while j<m:
            shad[ord(s[j])-ord('a')]+=1
            if j-i+1==n:
                if shad==phad:
                    ans.append(i)
                
                shad[ord(s[i])-ord('a')]-=1
                i+=1
            j+=1
        return ans
            
            
            

560. 和为 K 的子数组

在这里插入图片描述注意k可以为0,而return的count初始值如果是0的话,需要考虑避免这个0的问题。
当前累积和为cumulative_sum, 初始为0。
初始化一个哈希表sum_count,存储里面所有可能的和的值(键)和它们的个数(值),初始为{0:1},因为cumulative_sum初始为0。
所以我们不考虑计算和是否为k,而是计算当前和-k是否出现在sum_count中。如果出现过,就代表当前和-之前一部分累积和=k。
更新sum_count。

class Solution(object):
    def subarraySum(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        sum_count = {0: 1}  # 累积和: 计数
        cumulative_sum = 0
        count = 0
        
        for num in nums:
            cumulative_sum+=num
            #检查之前的累积和
            if cumulative_sum-k in sum_count:
                count+=sum_count[cumulative_sum-k]
            
            #更新哈希表
            if cumulative_sum in sum_count:
                sum_count[cumulative_sum]+=1
            else:
                sum_count[cumulative_sum]=1
                
        return count

239. 滑动窗口最大值

在这里插入图片描述算法:
滑动窗口遍历一次,每次数组中加入窗口中最大值, 但时间复杂度可能会随着输入数组的大小和窗口大小而变得很大。
创建一个单调递减的窗口遍历数组,始终保持最左侧的数是最大值,通过窗口遍历数组。

  1. 如果正在遍历的数大于窗口最右侧数,则窗口右侧缩小到窗口最小数≥这个数,形成单调递减。
  2. 将这个数加入窗口,如果窗口中数量大于k,移动窗口左侧。
  3. 如果窗口最右侧数的位置已经超过k,则窗口最左侧就是窗口的最大值。
from collections import deque

class Solution(object):
    def maxSlidingWindow(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        if not nums:
            return []
        window = deque()
        result = []
        for i, num in enumerate(nums):
            while window and nums[window[-1]] < nums[i]:
                window.pop()
            
            window.append(i)

            while i - window[0] > k - 1:
                window.popleft()
            
            if i >= k - 1:
                result.append(nums[window[0]])
        
        return result

76. 最小覆盖子串

在这里插入图片描述思路: 还是用双指针,一个数组table存储t的字母出现次数,一个数组stable存储存储s的字母出现次数,count计算子串中t的字母出现次数。
右指针遍历的字母:
更新stable,如果出现在table中, 更新count, while count==n:计算子串长度,和最小长度比较,如果更小就更新最小子串和最小长度; 左指针向右移动一位。

class Solution(object):
    def minWindow(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: str
        """
        m=len(s)
        n=len(t)
        table=[0]*128
        stable=[0]*128
        left,right=0,0
        ans=""
        minlen=float('inf')
        for char in t:
            table[ord(char)]+=1
        
        #记录当前窗口内字符的出现次数
        count=0
        
        while right<m:
            #更新右指针所指字符串计数
            stable[ord(s[right])]+=1

            if stable[ord(s[right])]<=table[ord(s[right])]:
                count+=1
            
            while count==n:
                if right-left+1<minlen:
                    minlen=right-left+1
                    ans=s[left:right+1]               
            
                stable[ord(s[left])]-=1
                if stable[ord(s[left])]<table[ord(s[left])]:
                    count-=1
                left+=1
            right+=1

        return ans

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值