Day39_1201
专注时间:6H09min
每日任务:计算机网络50分钟( 0 分钟),搜广推90分钟~上不封顶+手撕目录里的算法( 0 ),二刷hot100算法题 2 道(完成 5 道),刑法实务考试复习50分钟( 复习到 400页了 )
学习内容: 算法题二刷以及刑法实务复习
总结与心得: 周六周日休息了
《438.找到字符串中所有字母异位词》
python
class Solution(object):
def findAnagrams(self, s, p):
"""
:type s: str
:type p: str
:rtype: List[int]
"""
#只含小写字母,那么用哈希数组【26】做映射,用数组是否相等a==b就可以判断是否是异位词
#其实不用这样,利用一个for就够:固定大小的可滑动窗口,外层while是左指针startIndex,内层for是窗口大小 size = len(p)
res = []
if len(p)>len(s):
return res
lp,ls = len(p),len(s)
cnt_s = [0]*26
cnt_p = [0]*26
#在Python中,不能直接用字符串减去另一个字符串:p[i] - 'a' 是非法的。您需要使用 ord() 函数将字符转换为ASCII码值
for i in range(lp):
cnt_p[ord(p[i])-ord('a')]+=1
cnt_s[ord(s[i])-ord('a')]+=1
if cnt_p==cnt_s:
res.append(0)
i = 1
while i < ls-lp+1 :
cnt_s[ord(s[i-1])-ord('a')]-=1
cnt_s[ord(s[i+lp-1])-ord('a')]+=1
if cnt_p == cnt_s:
res.append(i)
i+=1
return res
《560.和为K的子数组》
python
class Solution(object):
def subarraySum(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
#还是想不起那些模型,前缀和。而且确实也没掌握用两数之和的思想解决前缀和只差的问题。依旧挫败感
#这里其实已经不可以滑动窗口了
#窗口元素和小于k时,往右扩大窗口;窗口和大于等于K时,窗口缩小通过左端点右移实现。
#[-1,-1,1] k=0 滑动窗口算法失效
#最简单直观的:暴力,注意不能排序,因为是子数组
#前缀和
s = [0] * (len(nums)+1)
sum = 0
for i in range(1,len(nums)+1):
sum += nums[i-1]
s[i] = sum
map = {}
res = 0
for i in range(0,len(nums)+1):
#要想清楚,需要查什么,查完之后需要存放什么
target = s[i]-k
if target in map:
res += map[target]
if s[i] not in map:
map[s[i]]=0
map[s[i]]+=1
return res
《239.滑动窗口最大值》
python
#from collections import deque
class Solution(object):
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
#要最大值,且滑动过程符合先进先出所以:单调递减的队列
#用left和right维持固定大小K的窗口,队列里的队头index与left比较,判断是否出队
que = []
res = []
# left [-k+1,len(nums)-k]
# right [0,len(nums)-1]
#初始化left,right = 1-k,0
n = len(nums)
#记一下这个数据结构
window = deque()
for right in range(n):
left = right - k + 1
#窗口形成,判断是否需要弹出队首
if window and window[0]<left:
window.popleft()
while window and nums[window[-1]]<nums[right]:
window.pop()
window.append(right)
#如果窗口已经形成,便开始记录答案
if left>=0:
#注意是window[0]因为长度一共就k
res.append(nums[window[0]])
return res
《76.最小覆盖子串》
python
class Solution(object):
def isCover(self,cnt_s,cnt_t):
for i in range(52):
if cnt_t[i]>cnt_s[i]:
return False
return True
def minWindow(self, s, t):
"""
:type s: str
:type t: str
:rtype: str
"""
if len(s)<len(t):
return ""
#数量大于等于,种类要一样。就是说两边数量要大于等于(但是不知道怎么写算法)
#满足上述条件时候,统计对比长度,如果长度更小,则更新当前最佳答案。
#最小覆盖子串。可以滑动窗口,一旦找到答案,就left++直至不符答案
left = 0
cnt_t = [0]*52
cnt_s = [0]*52
ans_left = -1
ans_right = len(s)
for str in t:
cnt_t[ord(str)-ord('a')]+=1
for right in range(len(s)):
cnt_s[ord(s[right])-ord('a')]+=1
while self.isCover(cnt_s,cnt_t):
if right-left < ans_right-ans_left:
ans_left = left
ans_right = right
cnt_s[ord(s[left])-ord('a')]-=1
left+=1
#"如果存在这样的子串,我们保证它是唯一的答案。"也就是说可能不存在这样的子串,要检查这种情况并返回""
if ans_left==-1:
return ""
return s[ans_left:ans_right+1]
《53.最大子数组和》
python
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
#dp[i]表示以nums[i]为结尾的最大连续喝子数组的和
#return max(dp)
dp = [0]*len(nums)
dp[0]=nums[0]
for i in range(1,len(nums)):
dp[i] = max(nums[i],nums[i]+dp[i-1])
return max(dp)