题目:
Given a string, find the length of the longest substring without repeating characters.
Examples:
Given "abcabcbb"
, the answer is "abc"
, which the length is 3.
Given "bbbbb"
, the answer is "b"
, with the length of 1.
Given "pwwkew"
, the answer is "wke"
, with the length of 3. Note that the answer must be asubstring, "pwke"
is a subsequence and not a substring.
题目要求,在给出的长字符串中,找出无重复的最长的子字符串,输出该子字符串的长度即可。思路比较简单,从头扫描长字符串,遇到重复即停下,记录子字符串长度。从下一位开始从新计数,重复前述步骤。两个点,一是判断重复,二是记录最大子字符串长度。第二点容易实现,设置变量max记录当前遇到的最大长度,设置变量cur记录当前子字符串长度,与max比较,决定是否更新max。第一点,最直观地,本想建立一个字符数组,记录当前子字符串出现过的字符,每次录入新字符就扫描查找是否重复。关键是,查找和判断(是否重复)。判断这一步骤肯定不能省下。能否在查找上省略呢?考虑到ASCII只能表示256个字符,建立一个大小为256的布尔数组,用于标记字符是否已经出现,视字符(ASCII码)为下标,便可直接找到对应字符,进而判断。
C++代码如下:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int n = s.length();
int x = 0, y = 0;
int max = 0;
int cur = 0;
bool sign[256] = {false};//此处利用ASCII共能表示256个字母,省去查找的步骤,一步到位判断是否重复
while(y < n) {
if(sign[s[y]]== false) {//无重复
sign[s[y]] = true;
y++;
}
else {//出现重复
//将x移动到新的子序列的首位,并且对前面的sign置零
while(s[x] != s[y]) {
sign[s[x]] = false;
x++;
}
sign[s[x]] = false;
x += 1;
}
cur = y - x;
max = max > cur ? max : cur;
}
return max;
}
};