leetcode-寻找最长不重复子串(第三题)
@2018-10-29
题目描述:
Given a string, find the length of the longest substring without repeating characters.
Example1:
Input: “abcabcbb”
Output: 3
Explanation: The answer is “abc”, with the length of 3.
Example2:
Input: “bbbbb”
Output: 1
Explanation: The answer is “b”, with the length of 1.
Example3:
Input: “pwwkew”
Output: 3
Explanation: The answer is “wke”, with the length of 3.
Note that the answer must be a substring, “pwke” is a subsequence and not a substring.
首先我们要理解最长不重复子串指的是什么, “abca"中的最长不重复子串为"abc”, 也就是说在一个子字符串中, 只要末尾和中间不是重复字符, 我们就可以认定这个字符串没有重复字符, 有了这个思想, 这道题就简单了许多.
我们可以用一个哈希表来存储各个字符出现的位置, 然后遍历字符串来确定最长不重复子串, 想象遍历字符串的过程是一个框, 假如遍历变量为 i (for(i = 0; i < str.length(); i++)), 那么每次i++以后, 这个框的右边界就右移一个字符, 右边界的移动情况就是这样, 那么我们来看一下左边界.
假如右边界移动一个字符后, 右边界现在所在的字符和这个框的字符串中某个字符一样, 此时这个框内的字符串就不是不重复子串了, 我们需要移动左边框的位置, 移动到哪里呢? 移动到框内的和右边界所在的字符相同的字符的左边, 举个例子, 框现在是"abcde", i++, 右边界右移一位, 假设变为了"abcdea", 那么我们此时需要移动左边框从’a’变为’b’, 所以框内的字符现在为"bcdea", 就是这么简单. 在此基础上, 我们再定义一个int型的变量(比如int max)来存储最长子串的长度就可以了, 遍历一次字符串就可以找出最长的不重复子串长度.最关键的还是用哈希表存储各个字符最新的位置, 这样max就可以随着字符串的遍历而更新.
代码中我们使用一个数组来代替哈希表, 因为ascii码有256个, 所以数组长度为256.
代码如下, 时间复杂度为O( n ):
int mymax(int a, int b)
{
return a > b ? a : b;
}
int lengthOfLongestSubstring(string str)
{
int asc[256] = { 0 };
int left = 0;
int max = 0;
int i;
/**
* @遍历
*/
for (i = 0; i < str.length(); i++)
{
/**
* @如果此字符以前出现过并且位置大于等于左边界
*/
if (asc[str[i]] >= left)
left = asc[str[i]];
max = mymax(max, i - left + 1);
asc[str[i]] = i + 1;
}
return max;
}