最长不含重复字符的子字符串(Python and C++解法)
题目:
请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof
思路:
使用滑动窗口(双指针)解题比较容易理解,维护字符串中的一个窗口不能有重复字符,同时更新窗口的最大值。
>>使用两个指针:head与tail。
>>tail指针右移,判断tail所指的元素是否在字符串的[head, tail)子串中:
>> 如果窗口中没有该元素,tail继续右移,往窗口中添加元素,同时跟新窗口最大长度;
>> 如果窗口中已经有该元素,则存在重复,将head右移直至窗口内不再有重复的元素。
注意:C++string的find函数当找到某一字符时,返回该字符的下标,当没有找到该字符时,返回一个特殊的标志位,用npos表示,本机npos取值是4294967295。
Python解法:
1 class Solution: 2 def lengthOfLongestSubstring(self, s: str) -> int: 3 if len(s) <= 1: 4 return len(s) 5 head, tail = 0, 0 6 maxLen = 1 7 while tail+1 < len(s): 8 tail += 1 # 往窗口内添加元素 9 if s[tail] not in s[head: tail]: # 窗口内没有重复的字符,实时更新窗口最大长度 10 maxLen = max(maxLen, tail - head + 1) 11 else: # 窗口内有重复字符,移动head直至窗口内不再含重复的元素 12 while s[tail] in s[head: tail]: 13 head += 1 14 return maxLen
C++解法:
1 class Solution { 2 public: 3 int lengthOfLongestSubstring(string s) { 4 if(s.size() <= 1) 5 return s.size(); 6 int head = 0, tail = 0, maxLen = 1; 7 while(tail + 1 < s.size()) { 8 tail += 1; // 往窗口内添加元素 9 // 如果窗口子串中没有找到重复字符 10 if(s.substr(head, tail - head).find(s[tail]) >= tail) 11 maxLen = max(maxLen, tail - head + 1); // 实时更新窗口最大长度 12 else // 如果窗口子串中存在重复字符 13 while(s.substr(head, tail - head).find(s[tail]) < tail) 14 head += 1; // 移动head直至窗口内不再含有重复的字符 15 } 16 return maxLen; 17 } 18 };