LeetCode第三题无重复字符的最长子串(Python)
题目描述
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例3:
输入: 输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题方法和思路
暴力求解
利用两个循环遍历所有情况求解,时间复杂度为 O ( n 2 ) O(n^2) O(n2)。
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
temp_length = 0
max_length = 0
for i in range(len(s)):
temp_s = set()
j = i
while s[j] not in temp_s:
temp_s.add(s[j])
j += 1
if j == len(s):
break
temp_length = len(temp_s)
if temp_length > max_length:
max_length = temp_length
return max_length
记录重复的字母的位置,进行优化
没有本质上的提升,只是优化了一部分冗余的情况,时间复杂度还是 o ( n 2 ) o(n^2) o(n2)。(ノへ ̄、)心累。
- 例如"abcdeff"的字符串,检测到"f"重复时会记录"f"的索引,直接将第一个循环的其实点跳转至前"f"的索引的下一个位置,也就是这个举例中的最后一个"f"的位置。
- 判断当前循环有无发生重复现象,若没有重复现象,这之后的不可能比当前的长度更加长,直接跳出循环,避免后续的无用计算。
核心代码:
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
temp_length = 0
max_length = 0
i = 0
while i < len(s):
temp_s = set()
repeat = 1
j = i
while s[j] not in temp_s:
temp_s.add(s[j])
j += 1
if j == len(s):
repeat = 0
break
temp_length = len(temp_s)
if temp_length > max_length:
max_length = temp_length
if repeat == 1:
i = i + s[i:j].index(s[j]) + 1
else:
return max_length
return max_length
滑动窗口
哇,看了解答才想到这么简单的思路,难受。w(゚Д゚)w。
贴一下别人的实现,只要遍历一次就可以实现任务,时间复杂度为
O
(
n
)
O(n)
O(n)。
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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。