剑指No.48_最长不含重复字符的子字符串
- 题目:请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
示例:输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
- 移动指针的做法(实际上双指针更佳)
public int lengthOfLongestSubstringWay(String s){
if (s == null || s.equals(""))
return 0;
HashMap<Character, Integer> subStringMap = new HashMap<>();
char[] chars = s.toCharArray();
int result = 0;
// 在循环体内改变i的值,进入下一次循环时会进行i++
for (int i = 0; i < chars.length; i++){
char ele = chars[i];
if (!subStringMap.containsKey(ele)){
subStringMap.put(ele, i);
result = Math.max(subStringMap.size(), result);
}else {
// 跳到上一个相同字符的下一位
i = subStringMap.get(ele);
subStringMap.clear();
}
}
return result;
}
- 动态规划
/**
* @Description:
* 1、状态定义:dp[i]代表以s[i]结尾的最大子字符串的长度
* 2、转移方程:(1)当前方无与s[i]相同的字符时,dp[i]=dp[i-1]+1
* (2)当前方有与s[i]相同的字符s[j]时,还要分为两种情况:
* 1_ i-j<=dp[i-1]的情况下,说明s[i-1]的最大子字符串中间没有其他相同的字符,可以直接用,则dp[i]=i-j
* 2_ i-j>dp[i-1]的情况下,说明s[j]到s[i]之间还有相同的字符,则dp[i]=dp[i-1]+1
*
* 3、输出:dp中最大值
* @Author: chong
* @Data: 2021/5/27 9:43 上午
*/
public class OfficialSolution {
public int lengthOfLongestSubstringWay(String s){
if (s.length() <= 1)
return s.length();
HashMap<Character, Integer> subStringMap = new HashMap<>();
int[] dp = new int[s.length()];
dp[0] = 1;
int res = 1;
subStringMap.put(s.charAt(0), 0);
for (int i = 1; i < s.length(); i++){
char ele = s.charAt(i);
if (!subStringMap.containsKey(ele)){
subStringMap.put(ele, i);
dp[i] = dp[i - 1] + 1;
}else {
int j = subStringMap.get(ele);
// 更新map到最近的相同字符
subStringMap.put(ele, i);
if (i - j <= dp[i - 1]){
dp[i] = i - j;
}else {
dp[i] = dp[i - 1] + 1;
}
}
res = Math.max(res, dp[i]);
}
return res;
}
}