class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
l, r = 0, 0
set1 = set() # 存储窗口的值
res = 0
ress = 0
while r < len(s):
q = s[r]
if q not in set1:
set1.add(q)
res += 1
ress = max(ress, res)
r += 1
else:
set1.remove(s[l]) # 这里!!!!
l += 1
res -= 1
return ress
l和r作为窗口的两端,set1.remove(s[l])这条语句是确保把左边界的元素去掉一直去到跟当前s[r]元素相同的左边的那个元素去掉,这时l就移到了跟当前s[r]元素相同的前面元素的下一位,就保证了当前连续子串没有重复元素,因为ress已经记录了最大连续字串值,所以去掉也不影响结果。这里set的作用和list是一样的,不要想着set保证唯一,加进去没事,就算用list里面也是没有重复元素的,那条语句的作用就是控制窗口的左端也就是l右移,确保窗口内元素唯一。
【以下回答由 GPT 生成】
问题标题: 为什么滑动窗口算法中一定是删除左指针指向的元素?
滑动窗口算法是一种用于解决字符串或数组中子串或子数组问题的常用技巧。具体到你提供的代码中,这个算法用于解决最长无重复字符子串的问题。在实际操作中,我们选择删除左指针指向的元素的原因如下:
左指针的移动导致窗口的左边界缩小:滑动窗口算法的核心思想是通过移动窗口的左右边界来更新窗口,并在每个位置上记录满足条件的子串的最优解。当左指针指向的元素不再属于当前窗口时,我们需要缩小窗口的左边界以保持窗口的有效性。这意味着我们需要删除窗口中当前左指针指向的元素。
删除左指针指向的元素不会导致遗漏最优解:在滑动窗口算法中,我们通过缩小窗口的左边界来寻找最优解。当我们删除左指针指向的元素时,窗口的大小减小,但是我们遍历到的位置仍然是满足条件的位置。因此,删除左指针指向的元素不会遗漏最优解。
删除左指针指向的元素可以保持窗口的有效性:删除左指针指向的元素意味着我们缩小了窗口的左边界,同时保证了窗口的右边界和左边界之间的元素是满足条件的。这样可以确保我们不会漏掉符合要求的解。
所以,在滑动窗口算法中,一般选择删除左指针指向的元素来更新窗口。这样操作可以保持窗口的有效性,并且不会遗漏最优解。
【相关推荐】