两道都花了至少4小时没能做出来,唉,多少有点挫败,看了评论区答案,自己感觉理解了还是写不出来,有返回去写。
感觉得调整心态,把看答案的这个过程看作是学习,做不出来的过程看作是理解题目,学习完答案后,再做题目或者触类旁通,就像高中数学一样,老师也是以例题来讲解知识点。恩,心理自我建设。
看到题目最先出现的想法是,对每个元素作为left,再从left+1的元素开始逐一判断,是否在前面连续子串中有重复出现过,如果有则记录当前的max lenth,更新left,重复上一过程。
问题:两层循环;如何判断字符是否重复出现过?(想的办法是记录前面出现的元素,新的元素去在这个里面找是否有重复)。显然这个方法费时,且判断left是否更新的条件那块,并不是很好写(以我目前浅薄的水平)
评论区高赞解答:
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
left, max_len,cur_len = 0, 0,0
strr = []
for i in range(len(s)):
cur_len += 1
while s[i] in strr:
strr.remove(s[left]) # 这里删除left真的很妙
left += 1
cur_len -= 1
if cur_len > max_len: max_len = cur_len
strr.append(s[i])
return max_len
最开始按照我自己的想法做时,我一直觉得和题目中的“滑动窗口”没什么关系,因为我的想法本质上是暴力循环所有连续子串,寻找无重复子串最长的长度。但是高赞解答的方法,在我看来:
- 并不用找出所有的子串
- 下一个元素与当前子串中元素有重合,删掉的不是重合的,而是像窗口滑动一样,右移左窗口(`.remove(s[left])`)——因为题目要求的是长度,而非子串是什么
438. 找到字符串中所有字母异位词 - 力扣(LeetCode)
最开始的想法应该是也类似与循环找出所有,但是实在是太暴力了
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
index, p_len, s_len= [], len(p),len(s)
if p_len>s_len: return []
char_s, char_p = [0]*26, [0]*26
for i in range(p_len):
char_p[ord(p[i])-97] +=1 # 判断元素是否相同,可以转化成判断不同元素出现次数是否相同
char_s[ord(s[i])-97] +=1 # 转化成字符对应的ascii码,避免了set()带来的重复元素被取消,以及list()元素有顺序,比较起来需要遍历的困难
if char_p==char_s: # 不然这里没法用==判定
index.append(0)
for j in range(s_len-p_len):
char_s[ord(s[j])-97] -= 1
char_s[ord(s[j+p_len])-97] +=1 # 很巧妙的地方 向前进
if char_s == char_p:
index.append(j+1) # i+1
return index
启发:
-
字符s与字符串strr判断是否有重合,可以转化成ASCII码的代号,用list存储,这样避免了很多问题......比如可以直接用判断两个列表是否相等来判定两个字符的关系,<不然像之前真的很难做,字符逐一提取先转换成列表(但是有顺序)/ 再转化成集合(重复字符无法 判断),只能一一对比,但是现在可以直接对比列表,是不是有些情况也可以这么处理,用一一对应的idx和值去指代>