[LeetCode] Longest Substring Without Repeating Characters 解题报告

来源:互联网 发布:戏剧打击乐器软件下载 编辑:程序博客网 时间:2024/06/16 05:13

—— write for my baby, mua


[题目]

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 a substring, "pwke" is a subsequence and not a substring.


[中文翻译]

给定一个字符串,求没有重复字母的最长子串的长度。

例子:

给定 "abcabcbb",最长子串为 "abc",长度为3。

给定 "bbbbb",最长子串为 "b",长度为1。

给定 "pwwkew",最长子串为 "wke",长度为3。注意,结果必须为子串,"pwke"是一个子序列而不是子串。


[解题思路]

O(N)

设字符串S下标i处的字母S[i]=A,那么以S[i]作结尾的没有重复字母的最长子串,受两个因素影响。

1. S[i]=A,A上一次出现的位置a

2. 所有已经出现的重复的字母对···B···B···、···C···C···、···,第一个字母中离S[i]最近的一个的位置,即max(B,C,···)=b

第一条很自然,因为出现了重复的A,那么子串最长只能是[a+1,i]。

第二条的原因是,子串[a+1,i]中,可能已经出现过重复的字母,而影响最长子串的,是所有已经出现的重复字母对中,第一个字母离S[i]最近的位置b,显然子串最长只能是[b+1,i]

综合1、2,没有重复字母的最长子串,只能是在[a+1,i]和[b+1,i]中取短的。


线性地遍历整个字符串,可以用一个数组int prePosition[128]记录每个字母上一次出现的位置,初始值设为-1,用一个整数int startBound记录最近出现重复字母对中第一个字母的位置,初始值设为-1。

在考虑S[i]作结尾的最长子串时,长度即为min(i-prePosition[S[i]], i-startBound)

考虑完S[i],如果prePosition[S[i]]>startBound,则更新startBound,因为出现了位置更近的重复的字母对中的第一个字母;然后再更新prePosition[S[i]]=i,因为在考虑S[i+1]时,上一次出现S[i]的位置已经变为了i。



[C++代码]

class Solution {public:int prePosition[128];void initPrePosition() {for (int i = 0; i < 128; i++)prePosition[i] = -1;}int lengthOfLongestSubstring(string s) {int max = 0;int startBound = -1;initPrePosition();for (int i = 0; i < s.length(); i++) {int prePos = prePosition[(int)s.at(i)];int len;if (prePos > startBound)len = i - prePos;elselen = i - startBound;if (len > max)max = len;if (prePos > startBound)startBound = prePos;prePosition[(int)s.at(i)] = i;}return max;}};


0 0
原创粉丝点击