一、题目描述
给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc"
,所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b"
,所以其长度为 1。
示例 3:
输入: s = "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是"wke"
,所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke"
是一个子序列,不是子串。
提示:
0 <= s.length <= 5 * 104
s
由英文字母、数字、符号和空格组成
二、分析
输入:1个string变量
输出:1个int变量
目的:
得到给定string中不含 重复字符 的最长的子串的长度
初步想法:
取出一个原字符串的字符,在存放“当前检视子串”但初始为空的一个vector中寻找这个字符,若没找到重复字符则将该字符加入子串并当前最长不重复字符子串长度+1;若找到重复字符则清除当前“当前检视子串”的内容和大小容量,但已找到的最长子串大小不会清除。
详细设计:
用1个int变量ult_length保存最终输出的最长不重复子串长度,1个int变量temp_length=0保存当前最长的不重复字符子串长度,1个元素为char类型变量的vector容器temp_sub来pushback保存当前进行判定的子串。然后用find(temp_sub.begin(), temp_sub.end(), target)来读取,读到的字符不是重复的就将该字符pushback到temp_sub然后继续读取原字符串中的下一字符,读取到重复字符时clear()然后shrink_to_fit()这个temp_sub,继续读取原字符串下一字符;temp_length会在每次读到不重复字符并装入temp_sub时+1(这样合适吗?),在读取到重复字符时将值赋给ult_length然后准备储存下一个子串的长度。
新知识:
子串(Substring)和子序列(Subsequence)的概念:子串是指原字符串中的连续字符序列,它必须是连续的、可以是空串、可以是原字符串本身。而子序列是指原字符串删除某些(也可以不删除)字符后剩下的字符保持原顺序不变形成的序列,它不一定是连续的,但出现的字符之间的顺序不能变,可以是空串、可以是原字符串本身。故子序列是比子串范围更大的概念,子序列包含子串,子串是特殊情况的子序列。
C++中vector清除元素、大小(size)、容量(capacity)的方法:v.clear(); v.shrink_to_fit();
erase(begin()+m,begin()+n)删除的是向量下标m到n-1的元素
三、代码实现
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int ult_length = 0;
int temp_length = 0;
vector<char> temp_sub(0);
for (size_t i = 0; i < s.size(); i++){
auto once_res = find(temp_sub.begin(),temp_sub.end(),s[i]);
if (once_res != temp_sub.end()) {
// 找到重复字符,更新 temp_sub 和 temp_length
temp_length = temp_sub.end() - once_res; // 重新计算目标串长度,从重复字符处开始
temp_sub.erase(temp_sub.begin(), once_res + 1);
temp_sub.push_back(s[i]);
} else {
// 没有找到重复字符,继续增加 temp_sub 和 temp_length
temp_sub.push_back(s[i]);
temp_length++;
if (temp_length > ult_length) {
ult_length = temp_length;
}
}
}
return ult_length;
}
};