题目:
请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
示例:
输入:"abcabcbb"
返回值:3(abc)
输入:"bbbbb"
返回值:1(b)
输入:"pwwkew"
返回值:3(wke)
解法1: 想法很简单,依次遍历字符串,用str来保存当前位置i之前的最长不重复子串,如果字符s[i]在之前遍历的字串str中没有出现,则str将该s[i]拼接到末尾,反之str则进行更新,将s[i]这个字符在str出现位置到i之间的字符子串,并且每次都比较一下str长度和之前保持的最长不重复字符。
例如:原串dabcabc
,当一直遍历到位置i=4
之前,都没有出现重复字符,因此str=dabc
,因为s[i]=a
在str的位置1出现,因此当前str更新为bca
,但是这时的str.leng=3
没有之前(str=dabc).length=4
长,所以不更新maxLen
function lengthOfLongestSubstring( s ) {
// write code here
let str=s[0];
let maxLen = 1;
for(let i=1;i<s.length;i++){
if(!str.includes(s[i])){
str+=s[i];
}else{
var d = str.lastIndexOf(s[i]);
str = str.slice(d+1)+s[i];
}
maxLen = maxLen<str.length ? str.length : maxLen;
}
return maxLen
}
这种算法思想时间复杂度O(n),空间复杂度O(1)
解法2: 第二种思想是动态规划,设动态规划列表dp[j]
代表以字符s[j]
为结尾的最长不重复字符串的长度,设s[j]左边距离最近的相同字符为s[i],即s[i]=s[j]
转移方程:
- 当
i小于0
,即s[j]
左边无相同字符,则dp[j]=dp[j-1]+1
- 当
dp[j-1]<j-i
,说明字符s[i]
在字符串dp[j-1]
区间之外,则dp[j]=dp[j-1]+1
- 当
dp[j-1]≥j-i
,说明s[i]在字符串dp[j-1]区间之中,则dp[j]=j-i
详细解法见下面链接
https://leetcode-cn.com/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/solution/mian-shi-ti-48-zui-chang-bu-han-zhong-fu-zi-fu-d-9/