题目描述:
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
示例 4:
输入: s = ""
输出: 0
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
第一眼思路:
首先,是要找一个序列中的子序列,有一个暴力的思路就是找出这个序列的所有子序列,然后判断有无重复元素。可行
是否有更优解?
能否找出所有重复字符所在的位置,从前从后判断,剩下的就是不重复的字符了,然后选择一个最长的字串
想到enumerate方法可以输出字符串的位置以及数据,那么就可以实现找出所有字符所在位置这一步。问题在于,如何知道是重复的?判断是否跟前一个元素相同
3/3看一下别人写的程序先
滑动窗口法有点不理解
实现代码该怎么实现,两个指针
3/4
小乌龟继续更,今天比昨天的我更好,绝不放弃。。。
今天又看了一下其他人写的关于指针的解答,好像更加理解了一点了
思路:
这道题主要用到思路是:滑动窗口
什么是滑动窗口?
其实就是一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列!
如何移动?
我们只要把队列的左边的元素移出就行了,直到满足题目要求!
一直维持这样的队列,找出队列出现最长的长度时候,求出解!
时间复杂度:O(n)O(n)
代码:
PythonC++Java
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
if not s:return 0
left = 0
lookup = set()
n = len(s)
max_len = 0
cur_len = 0
for i in range(n):
cur_len += 1
while s[i] in lookup:
lookup.remove(s[left])
left += 1
cur_len -= 1
if cur_len > max_len:max_len = cur_len
lookup.add(s[i])
return max_len
作者:powcai
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/hua-dong-chuang-kou-by-powcai/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
自己的理解:
滑动窗口法:
其实这个指针就相当于一个滑动的窗格,
>一开始右边的指针不停地向右滑动,这个动作是要一直进行的,那么我们需要一个变量current_len来记录右边指针的位置变化引起的字串长度变化(其实有点不太准确,因为左边指针往右滑动的话,current_len是要-1的,其实就相当于记录的是当前子串长度,但为了你可以想象出一个指针,可以这么理解)
>然后还需要一个left变量,记录左边指针长度变化,
>紧接着我们就开始遍历元素了,遍历的过程中把元素append到一个列表里面,来检查是否重复/(网友代码用的是空set,set添加元素用的add()方法;我这里用的list,现在还不太清楚二者具体区别)
>如果元素跟lookup内元素不是重复的,那么就一直添加,右边指针继续滑动
>如果重复,删除一个左边元素,左边指针往右滑动。然后再while循环里进行同样的动作,直到没有重复的元素为止。(其实可以就把lookup想成显示窗格)
>结束一轮循环后,需要借助max_len来比较每一轮current_len的长度,从而找出最大
代码如下:
》然后这里有几个注意的小细节:
①用for在遍历元素时,遍历的是数字,务必记得加range()
不足以后继续更新。。