题目链接
https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
题目描述
给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。注意是最长子串而不是最长子序列。子串是连续的。
示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 示例 2: 输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 示例 3: 输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。 示例 4: 输入:“dvdf” 输出:3
解题思路
1.遇到字符串类型的题目,可以立马联想暴力搜索的方法,而后可以采用诸如双指针、滑动窗口等进行优化。
解法一:暴力搜索
双重for循环,利用map或者set进行重复元素的判定,统计从每个字符开始的最长不重复子串并且利用maxx变量进行迭代更新。
解法二:双指针或者称为滑动窗口进行优化
保证i、j指针内没有重复元素,一直动态维护i、j两个指针,或者说动态维护左右边界为i、j的滑动窗口,不重复子串的长度为j-i+1。
AC代码
解法一:暴力搜索
1 class Solution { 2 public: 3 int lengthOfLongestSubstring(string s) { 4 if(s == "") return 0; 5 else 6 { 7 int maxx = 1; 8 for(int i = 0; i < s.length(); i++)//利用双重for循环统计每个字符开始的最长不重复子串。 9 { 10 map<char,int> mp; //利用map容器进行重复字符判定 11 int ans = 0; 12 for(int j = i; j < s.length(); j++) 13 { 14 if(mp[s[j]] > 0) 15 { 16 if(ans > maxx) maxx = ans; //利用maxx进行迭代更新答案。 17 break; 18 } 19 else 20 { 21 mp[s[j]]++; 22 ans++; 23 } 24 } 25 if(ans > maxx) maxx = ans; 26 } 27 return maxx; 28 } 29 } 30 };
解法二:双指针(滑动窗口)
1 class Solution { 2 public: 3 int lengthOfLongestSubstring(string s) { 4 if(s.size() == 0) return 0; 5 if(s.size() == 1) return 1; 6 int l = 0;//l、r滑动窗口的左右界,或者可以理解为双指针 7 int r = 0; 8 int ans = -1; 9 set<char> st; //利用set集合进行重复元素判断 10 while(l <= r && r < s.size()) 11 { 12 if(st.count(s[r]) == 0) 13 { 14 st.insert(s[r]); 15 ans = max(ans,r-l+1); 16 r++; 17 } 18 else 19 { 20 st.erase(s[l]); 21 l++; 22 } 23 } 24 return ans; 25 } 26 };