题目
请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
示例 1:
输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
提示:
s.length <= 40000
分析
一般求这种最长字符串长度很多都采用动态规划问题,首先确定dp[i]的含义,它代表以第i个下标字符为结尾的最长的不包含重复字符的子字符串的长度。
分情况讨论确定动态规划表达式
需要使用哈希函数来保存字符和其对应的下标
确定初始值,dp[0]为1。
优化空间复杂度,dp[i] = dp[i-1]+1;化成单一变量 a = a+1;
代码
class Solution {
public int lengthOfLongestSubstring(String s) {
if(s == null || s.length()<=0){
return 0;
}
Map<Character,Integer> map = new HashMap<>();
int[] dp = new int[s.length()];
dp[0]=1;
map.put(s.charAt(0),0);
int res = 1;
for(int i=1;i<s.length();i++){
if(!map.containsKey(s.charAt(i))){
dp[i] = dp[i-1]+1;
}else{
int k = map.get(s.charAt(i));
if(i-k<=dp[i-1]){
dp[i] = i-k;
}else{
dp[i] = dp[i-1]+1;
}
}
res = Math.max(res,dp[i]);
map.put(s.charAt(i),i);
}
return res;
}
}
class Solution {
public int lengthOfLongestSubstring(String s) {
if(s == null || s.length()<=0){
return 0;
}
Map<Character,Integer> map = new HashMap<>();
int a = 1;
map.put(s.charAt(0),0);
int res = 1;
for(int i=1;i<s.length();i++){
if(!map.containsKey(s.charAt(i))){
a = a+1;// 就是没有刷新 a 之前,a表示dp[i-1]
}else{
int k = map.get(s.charAt(i));
if(i-k<=a){
a = i-k;
}else{
a = a+1;
}
}
res = Math.max(res,a);
map.put(s.charAt(i),i);
}
return res;
}
}