给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
解答:
用动态规划的方法,将问题分解为计算当前字符与其之前的字符串可以组成的不重复字符串长度。
p | w | w | k |
---|---|---|---|
1 | 2 | 1 | 2 |
使用String的函数解决计算当前字符与其之前的字符串可以组成的不重复字符串长度的问题。
public static int lengthOfLongestSubstring(String s) {
if (s.isEmpty()) return 0;
int max = 0;
int[] a = new int[s.length()];
a[0] = 1;
for (int i = 1; i < s.length(); i++) {
int y = s.indexOf(s.charAt(i), i - a[i - 1]);
if (y == i) {
a[i] = a[i - 1] + 1;
} else {
a[i] = i - y;
}
if(a[i] > max) max = a[i];
}
return max;
}
使用HashMap记录各个字符最后一次出现的位置,解决计算当前字符与其之前的字符串可以组成的不重复字符串长度的问题。
public int lengthOfLongestSubstring(String s) {
int ans = 0;
Map<Character, Integer> map = new HashMap<>(); // current index of character
// try to extend the range [i, j]
for (int j = 0, i = 0; j < s.length(); j++) {
char c = s.charAt(j);
if (map.containsKey(c)) {
i = Math.max(map.get(c), i);//计算最近重复字符出现位置,更新i
}
ans = Math.max(ans, j - i+1);//计算最长距离
map.put(c, j+1);//存储字符最后一次出现位置
//System.out.println(s.substring(i, Math.min(i + ans,s.length() - 1)));//打印子串
}
// System.out.println(map);
return ans;
}