力扣每日刷题251113
今天听了同门的学习方法醍醐灌顶,以后不再死磕题目了,以后应该会每日做多一点题目。
题目一:

这是一个很有意思的题目,首先我们先分析一下,当我们从左到右都取最高值然后用最高值减去当前有的值的时候,我们会发现,过了最高点之后,后面的雨水就不正常了。如下图一所示。从右往左亦然。那我们可以这样两边的最高值为两边的最小值就可以了!这样从左往右扫一遍,再从右往左扫一遍,最后两个数组跟原始的高度再扫一遍,就可以得到雨水的数量了。

下面是我看了题解后的自己的输入:
class Solution:def trap(self, height: List[int]) -> int:if not height:return 0n =len(height)L_max = [height[0]] + [0]*(n-1)R_max = [0]*(n-1) +[height[n-1]]for i in range(1,n):if height[i] > L_max[i-1]:L_max[i] = height[i]else:L_max[i] = L_max[i-1]for i in range(1,n):if height[n-1-i] > R_max[n-i]:R_max[n-i-1] = height[n-1-i]else:R_max[n-i-1] =R_max[n-i]res = sum([min(L_max[i],R_max[i]) - height[i] for i in range(n)])return res
这部分是题解的内容:原谅我没记住哈哈哈哈
class Solution:def trap(self, height: List[int]) -> int:if not height:return 0n = len(height)leftMax = [height[0]] + [0] * (n - 1)for i in range(1, n):leftMax[i] = max(leftMax[i - 1], height[i])rightMax = [0] * (n - 1) + [height[n - 1]]for i in range(n - 2, -1, -1):rightMax[i] = max(rightMax[i + 1], height[i])ans = sum(min(leftMax[i], rightMax[i]) - height[i] for i in range(n))return ans
其实还有另外一个题解,我以后再看吧哈哈哈。
第二题:

官方的题解真的是让人费解啊。正常来说我们的思维是这样:
1.设置两个指针,一个左指针,一个右指针,左指针负责告诉我什么地方开始的,右指针负责探索。
2.当右指针发现他找到的字符与我们存储的字符有重复的时候,左指针可以一步一步地找,找到重复的字符并蹦出字符后,右指针才可以继续移动。
知道上面两个思路后我们开始写自己的代码:
我们首先先设置一个右指针 R 与一个集合 str_set 。其中集合的作用是存储我们的字母,判断下一个指向的字母在不在我们的集合当中。
然后我们用一个for循环来引出我们的左指针,左指针就是从左往右扫的一个作用,那它什么时候可以扫呢?1.最容易忽视的:在我们的右指针扫到头的时候即R+1=n的时候。2.当我们右指针指的下一个元素在我们的set当中时:s[R+1] in set。这两个条件不成立的时候。我们可以把右指针指向的元素加入到我们的KFC全家桶(bushi 因为今天是周四玩一下梗哈哈哈。加入我们的集合s当中。并且右指针向右边移动。
最后其实也是一个代码的难点:就是数据的更新:这里我是记住了用max(res,R-L+1)这种方式可以进行一个更新。这也算是一个提醒吧。这种化简的更新方式其实不容易想到的哈哈哈哈。
class Solution:def lengthOfLongestSubstring(self, s: str) -> int:str_set = set()R , n = -1 , len(s)res = 0for L in range(n):if L != 0:str_set.remove(s[L-1])while R+1<n and s[R+1] not in str_set:str_set.add(s[R+1])R +=1res = max(res,R-L+1)return res
第三题:

上面是这道题,下面是我的题解:虽然没跑通(超时)但是非常朴素哈哈哈哈哈,就是用一个窗口直接划过去,如果里面的元素都相同就返回相应的序号。
class Solution:def findAnagrams(self, s: str, p: str) -> List[int]:n_p = len(p)n_s = len(s)res = []for i in range(n_s - n_p +1 ):if sorted(s[i:i+n_p]) == sorted(p):res.append(i)return res
上面这种要是不考虑计算资源的话我个人认为应该是可以的。
那我们再看看官方怎么说:
class Solution:def findAnagrams(self, s: str, p: str) -> List[int]:s_len, p_len = len(s), len(p)if s_len < p_len:return []ans = []s_count = [0] * 26p_count = [0] * 26for i in range(p_len):s_count[ord(s[i]) - 97] += 1p_count[ord(p[i]) - 97] += 1if s_count == p_count:ans.append(0)for i in range(s_len - p_len):s_count[ord(s[i]) - 97] -= 1s_count[ord(s[i + p_len]) - 97] += 1if s_count == p_count:ans.append(i + 1)return ans
官方的题解是这样的:
26个字母先做个用于统计字母数量的列表。首先先统计需要查询字符的字母列表其中用到了ord去转化ascll码。第二步,去判断是否s与p长度相同,如果相同的话就直接回0就可以了。最后开始滑动窗口,窗口滑动其实就是左出右进。上面的思路就是这样。下面是我按照上面思路自己写的内容。
class Solution:def findAnagrams(self, s: str, p: str) -> List[int]:l_s = len(s)l_p = len(p)count_s = [0] * 26count_p = [0] * 26res = []if l_s < l_p:return []for i in range(l_p):count_p[ord(p[i]) -97] += 1count_s[ord(s[i]) -97] += 1if count_p == count_s :res.append(0)for i in range(l_s - l_p ):count_s[ord(s[i])-97] -= 1count_s[ord(s[i+l_p])-97] += 1if count_p == count_s:res.append(i+1)return res
哈哈哈哈,怎么跟上面的题解一样有点有趣哈哈哈哈。看来高手都是相同的手动狗头。还是花了将近半个小时啊!
今天先到这里吧
