给定一个字符串?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
?由英文字母、数字、符号和空格组成//无重复字符的最长子串
//求不含有重复字符串的子串的最长长度
//连续一段元素的关系
//滑动窗口(同向双指针)
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
string s;//字符串
int result = 0;//结果
int n;//字符串长度
int c[126];//标记字母使用次数
//滑动窗口
void lols(){
//初始化字母使用次数
for(int i = 0;i < 126;i++){
c[i] = 0;
}
int left = 0,right;//左右指针
//循环右移右指针
for(right = 0;right < n;right++){
//将右侧元素并入子数组
while(c[s[right] - ' ' + 1] != 0 && left <= right){
//有重复元素了
c[s[left] - ' ' + 1]--;
//左指针左移
left++;
}
c[s[right] - ' ' + 1]++;
result = max(result,right - left + 1);
}
}
int main(){
//输入正整数数组
/*int t;
while(cin.peek() != '\n'){
scanf("%d",&t);
nums.push_back(t);
}*/
//输入字符串
//读入字符串时会以空格为分隔符,如果输入的字符串中包含空格则只会读取空格之前的部分,空格后面的内容将被丢弃
//cin >> s;
//读入一行字符串,包括空格
//位于string头文件中
getline(cin,s);
//-------------------------------
n = s.length();//字符串长度
//滑动窗口
lols();
//输出结果
printf("%d",result);
return 0;
}
解题思路:题目求最长子串长度,属于连续一段元素的关系,适合使用滑动窗口(同向双指针)。用数组c存储各个元素在子串中的使用次数,利用ASCII码换算下标,在字母、数字、符号、空格中,空格的ASCII码最小(32),ASCII码最大的符号的ASCII码值为126。
注意:
????????命名时尽量不要使用count,会和STL中的count撞名。
? ? ? ? cin不会读取空格,它只会读取空格前面的内容,其余内容丢弃。
? ? ? ? 想读取整行内容时使用getline(cin,s),位于头文件<string>。
? ? ? ? 使用字符串要加上头文件<string>。
? ? ? ? 对于string类型的变量,如果使用scanf输入,需要格式为scanf("%s",s.c_str());。