Problem
Given a string, find the length of the longest substring without repeating characters.
Examples:
Given “abcabcbb”, the answer is “abc”, which the length is 3.
Given “bbbbb”, the answer is “b”, with the length of 1.
Given “pwwkew”, the answer is “wke”, with the length of 3. Note that the answer must be a substring, “pwke” is a subsequence and not a substring.
Solution
求一个字符串中长度最长的没有重复字符的子串(注意不是子序列:子串是原字符串中连续的一段,子序列只要保证字符排列仍按照原字符串的顺序就行),这是一道经典的动态规划题。假设原字符串长度为n,dp[n] 是动态规划数组,用于存储计算过程中的中间值,dp[i] 代表从字符串开始到第i个位置这段上最长的不含重复元素的子串长度。显然dp[0] = 1,i 从1到n - 1上,dp[i] 有两种情况,一种是不含第i个字符,这种情况下dp[i] = dp[i - 1];另一种情况是含第i个字符,此时我们用一个helper函数计算从第i个字符依次往前递推到头最长的不含重复元素的子串长度,用一个hashSet 记录,只要遍历到重复元素即终止。最终的dp[i]是这两种情况下的最大值,本题的结果是dp[n - 1]。
import java.util.HashSet;
public class Solution {
public int lengthOfLongestSubstring(String s) {
char[] arr = s.toCharArray();
int len = arr.length;
if(len==0) return 0;
int[] dp = new int[len];
dp[0]=1;
for(int i=1;i<len;i++){
dp[i]=Math.max(dp[i-1],helper(arr,i));
}
return dp[len-1];
}
public int helper(char[] arr, int index){
HashSet<Character> map = new HashSet<>();
int k = index;
int res = 0;
while(k>=0 && !map.contains(arr[k])){
res++;
map.add(arr[k]);
k--;
}
return res;
}
}