问题
来自力扣:
请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
我的代码
#include <iostream>
using namespace std;
#include <algorithm>
#include <vector>
#include<queue>
#include <typeinfo>
#include <numeric>
#include<cmath>
#include<map>
#include<string>
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int maxlen = 0, clen = 0;
char tmp;
map<char, bool> charm;
queue<char> charq;
//vector<char> charv;
for (int i = 0; i < s.size(); ++i) {
charq.push(s[i]);
if (charm.find(s[i])==charm.end()|| charm.find(s[i])->second==false) {
charm[s[i]] = true;
}
else {
while (!charq.empty()) {
tmp = charq.front();
if (s[i] == tmp) {
charq.pop();
cout << "find"<<charq.size();
break;
}
charq.pop();
cout << s[i] << " be set false"<<tmp;
charm[tmp] = false;
}
}
for (auto a : charm) {
cout << a.first << a.second << " ";
}
cout << charq.size() << endl;
if (maxlen < charq.size())
maxlen = charq.size();
}
return maxlen;
}
};
int main() {
string s = "pwwkew";
Solution mysolution;
int a = mysolution.lengthOfLongestSubstring(s);
cout << a;
return 0;
}
这道题的解题思路和笔记18很像。
我用一个队列q和一个map。
q用来将每个字符压入,如果发现字符重复了,就pop直到不重复。
map是记录目前q中还有哪些字符的(我感觉用map怪怪的,但是没想到好的方法。)
maxlen则是一直记录q的最大长度。
示例代码
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int ans = 0;
int a[256] = {0}; //用来保存每个字符出现的次数,初始化为0
for(int i = 0, j = 0; i < s.size(); i ++){
a[s[i]]++;
while(j < i && a[s[i]] > 1){//若右指针i的字符si出现>1次
a[s[j]]--;//右移左指针即删除最左字符,直到si仅出现一次
j ++;//例如abcdd-bcdd-cdd-dd-d.
}//每次跳出循环即得到一个无重复字符的子串
ans = max(ans, i - j + 1);//比较子串长度得到最大值即可
}
return ans;
}
};
我本来也想用一个数组来记录字符是否出现的,因为很方便,每个字符都对应1个ascii码。但是我以为只有26个小写字母,就创建了1个长度26的数组,测试代码的时候发现有其他的字符,然后我的代码报错了。所以才改得那么复杂。
看了示例代码后又去查了下ascii码表,好像它是固定的,就是0~255。又学到了。