原题链接地址
传送门:https://leetcode-cn.com/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/
题目原文
请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
提示:
s.length <= 40000
题解:动态规划
假设dp[i]表示到第i个字符为止,最长不含重复字符的子字符串长度,那么我们只需要知道dp[i-1]的值以及截止到第i-1个字符的子串中是否包含了第i个字符,这呈一个递推的最优子结构。所以使用动态规划算法解决。
dp[i]表示到第i个字符为止,最长不含重复字符的子字符串长度;
occur[i]表示第i个字符上次在字符串中出现的下标的下一位,比如“abcabcd"对应的occur={0,0,0,1,2,3,0}.
所以能得到如下转移方程:
d
p
[
i
]
=
{
d
p
[
i
−
1
]
+
1
o
c
c
u
r
[
i
]
<
i
−
d
p
[
i
−
1
]
截
止
到
第
i
−
1
个
字
符
的
子
串
中
不
包
含
了
第
i
个
字
符
i
−
o
c
c
u
r
[
i
]
+
1
o
t
h
e
r
s
dp[i]=\left\{\begin{matrix} dp[i-1]+1& occur[i] < i-dp[i-1] & 截止到第i-1个字符的子串中不包含了第i个字符 \\ i-occur[i]+1 & others & \end{matrix}\right.
dp[i]={dp[i−1]+1i−occur[i]+1occur[i]<i−dp[i−1]others截止到第i−1个字符的子串中不包含了第i个字符
public:
int lengthOfLongestSubstring(string s) {
if(s.size()<=1)return s.size();
vector<int>chars(128,-1);
vector<int>occur(s.size(),0);
vector<int>dp(s.size(),0);
for(int i=0;i<s.size();i++){
occur[i]=chars[s[i]]+1;
chars[s[i]]=i;
}
int ans=0;
dp[0]=1;
for(int i=1;i<s.size();i++){
int start = i-dp[i-1] > occur[i]?i-dp[i-1]:occur[i];
dp[i]=i-start+1;
ans = ans<dp[i]?dp[i]:ans;
}
return ans;
}
[1] https://leetcode-cn.com/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/solution/