题目
请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
代码实现
双指针实现
class Solution {
public int lengthOfLongestSubstring(String s) {
char[] chars = s.toCharArray();
int max = 0;
Map<Character,Integer> map = new HashMap<>();
int left = 0,right = 0;
for (int i = 0; i < chars.length; i++) {
Integer index = map.get(chars[i]);
//之前已经有这个字符
if(index != null){
left = Math.max(index + 1,left);
}
right++;
map.put(chars[i],i);
max = Math.max(max,right - left);
}
return max;
}
}
动态规划
方法一:动态规划 + 哈希表
class Solution {
public int lengthOfLongestSubstring(String s) {
Map<Character, Integer> dic = new HashMap<>();
int res = 0, tmp = 0;
for(int j = 0; j < s.length(); j++) {
int i = dic.getOrDefault(s.charAt(j), -1); // 获取索引 i
dic.put(s.charAt(j), j); // 更新哈希表
tmp = tmp < j - i ? tmp + 1 : j - i; // dp[j - 1] -> dp[j]
res = Math.max(res, tmp); // max(dp[j - 1], dp[j])
}
return res;
}
}
方法二: 动态规划 + 线性遍历
class Solution {
public int lengthOfLongestSubstring(String s) {
Map<Character, Integer> dic = new HashMap<>();
int res = 0, tmp = 0;
for(int j = 0; j < s.length(); j++) {
int i = j - 1;
while(i >= 0 && s.charAt(i) != s.charAt(j)) i--; // 线性查找 i
tmp = tmp < j - i ? tmp + 1 : j - i; // dp[j - 1] -> dp[j]
res = Math.max(res, tmp); // max(dp[j - 1], dp[j])
}
return res;
}
}