题目全部来自力扣
3.无重复字符的最长子串(滑动窗口方法)
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: s = “bbbbb”
输出: 1
-解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
示例 4:
输入: s = “”
输出: 0
- 思路:
根据官方推荐的滑动窗口,什么是滑动窗口. 比如说字符串abcabcdd,第一次找的时候起始位置为a,之后向后查找,当找到abca的时候发现有重复,移除第一个字符串’a’,此时从b开始查找,再向后面查找,当再次找到重复字符串的时候,移除字符串第一个’b’,从c开始查找,依次类推,找到不重复的最长的字符串.
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
n = len(s)
a = set()
ans, rk = 0, -1
for i in range(n):
if i > 0:
a.remove(s[i-1])
while rk+1 < n and s[rk+1] not in a:
a.add(s[rk+1])
rk+=1
if s[rk+1] in a:
a.index(s[rk+1])
ans = max(ans,rk+1-i)
return ans
class Solution {
/**
* @param String $s
* @return Integer
*/
function lengthOfLongestSubstring($s) {
$len = strlen($s);
$arr = array();
$max = 0;
$end = -1;
for($i = 0; $i < $len; $i++) {
if($i > 0) {
unset($arr[$i-1]);
}
while($end+1 < $len && !in_array($s[$end+1], $arr)) {
$arr[] = $s[$end+1];
$end+=1;
}
$max = max($max, $end+1-$i);
}
return $max;
}
}
这个是优化滑动窗口方法之后的,比如’abcdfcrg’,我们得到’abcdf’之后,再下面是’c’,判断到有重复字符的时候,起始位置直接从’ancdf’中重复的字符’c’之后开始,也就相当于起始下标从3开始,再去向后面查找不重复子串
import sys
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
n = len(s)
if n < 2:
return n
tail = 1
start = 0
count = 0
a = set()
while tail < n:
while tail < n and s[tail] not in s[start:tail]:
tail += 1 # 9
count = max(count,tail-start) # 7
# 注意下面是 += 所以是s[start:tail] 在之前的基础上+
if tail < n:
start += s[start:tail].index(s[tail])+1 # 1
return count