Description
Given a string, find the length of the longest substring without repeating characters.
Difficulty
Medium
Example1
Input: "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.
Example2
Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.
Example3
Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.
Solution
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) return 0;
int length = s.length();
//dp[i]用于存放字符串 s 中 0 ~ i 中,包含字符s.charAt[i]的最长无重复子串
int[] dp = new int[length];
dp[0] = 1;
//maxLength 时刻记录当前最大无重复子串
int maxLength = 1;
for (int i = 1; i < length; i++) {
for (int j = i - dp[i - 1]; j < i; j++) {
//情况1:在dp[j ~ (i - 1)] 中的存在一个数等于dp[i],则 dp[i] = i - j(从相同字符的下个字符到dp[i]的长度)
if (s.charAt(i) == s.charAt(j)) {
dp[i] = i - j;
break;
//情况2:在dp[j ~ (i - 1)] 中的每个数均不等于dp[i],则 dp[i] = dp[i - 1] + 1
} else if (j == i - 1) {
dp[i] = dp[i - 1] + 1;
}
maxLength = dp[i] > maxLength ? dp[i] : maxLength;
}
}
return maxLength;
}
}
Summary
- 典型的动态规划,每个字符所组成前导最大无重复子串依赖于上一个字符前导无重复子串
- 情况1:dp[i] = dp[i - 1],字符串 s 在dp[i - 1] ~ i - 1 范围内的数均不等于s.charAt(i)
- 情况2:dp[i] = i - j,字符串 s 在dp[i - 1] ~ i - 1 范围内,存在与s.charAt(i)相同字符,截取该字符到 i 的距离作为dp[i]的值