无重复字符的最长子串
Posted yulongzhou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无重复字符的最长子串相关的知识,希望对你有一定的参考价值。
无重复字符的最长子串
题目链接: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" 是一个子序列,不是子串。
思路:
暂时想到解法有二:
1. 暴力做: 将当前的字符串的所有子串全数枚举,然后计算所有没有重复子串的长度,但此时间复杂度为O(n^2), 尝试提交,分别为超时和超内存(leetcode给出的最后一个样例的长度为3万多)。
2. 滑动式: 从第一个字符开始,依次向字符串尾滑动一个字符,若滑动一个字符后仍没有重复字符,则记录其长度。若有重复则将第一次出现及其以前的字符全部舍去成为一个新的字符串,重复滑动。时间复杂度为O(n)。可正常提交通过。
2例如下:
假设源字符串:“1234256”
- 初始选择“1”:“1234256”,
- 上面没有重复,则向右滑动一个字符:“1234256”,并记录并可能子串长度(如果此时子串比已记录最长长度未重复子串长度长则更新最长子串记录)[拗口.jpg]
- 上面没有重复,向右滑动:“1234256”,并记录长度
- 上面没有重复,向右滑动:“1234256”,并记录长度
- 上面没有重复,向右滑动:“1234256”,并记录长度
- 上面出现重复,因为此时两个“2”不能同时出现在一个子串上(我们需要不重复子串)且包含第一个“2” 以及 不能被包含第二个“2”的子串使用的(能和第一个“2”组成子串,不能和第二“2”组成子串的字符串)最长字符串为“12”,故舍去“12”,之后右滑一个字符:“34256”
- 上面没有重复,向右滑动:“34256”,并记录长度;
- 上面没有重复,无法向右滑动,并记录长度
- 故最长不重复子串为“34256”,长度为 5
代码参考(随便写的,需要优化):
#include <iostream> #include <string> using namespace std; class Solution { public: // 查找是否重复,若有重复则返回重复数字下标,若没有重复,则返回-1 int isRepeat(string s, string sub) { if (s.find(sub) == s.npos) { return -1; } else { return s.find(sub); } } int lengthOfLongestSubstring(string s) { if (s.length() == 0 && s.length() == 1) return s.length(); int maxSize(0); string substring = s.substr(0,1); for (int i = 1; i < s.length() ; ++i) { string temp = s.substr(i, 1); int repeatPosit = isRepeat(substring, temp); if(repeatPosit == -1) { substring.append(temp); if(substring.length() > maxSize) { maxSize = substring.length(); } } else { substring.append(temp); substring = substring.substr(repeatPosit+1); } } return maxSize; } }; int main () { Solution solution; string s("1234256"); cout << solution.lengthOfLongestSubstring(s) << endl; }
以上是关于无重复字符的最长子串的主要内容,如果未能解决你的问题,请参考以下文章