问题:
给定一个字符串,找出不含有重复字符的最长子串的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 无重复字符的最长子串是 "abc",其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 无重复字符的最长子串是 "b",其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 无重复字符的最长子串是 "wke",其长度为 3。
请注意,答案必须是一个子串,"pwke" 是一个子序列 而不是子串。
思路
- 思路1:两循环来获取所有子串,通过HashMap判断字符是否重复
public static int lengthOfLongestSubstring(String s) {
int len = 0;
Map map = new HashMap();
for (int i = 0; i < s.length(); i++) {
for (int j = i; j < s.length(); j++) {
char tmp = s.charAt(j);
if (map.containsKey(tmp)) {
len = len < map.size() ? map.size() : len;
map.clear();
break;
} else {
map.put(tmp, tmp);
}
}
}
len = len < map.size() ? map.size() : len;
return len;
}
- 思路2:一个循环,通过HashMap存放在字符串中最大位置,通过变量和最大位置差获得结果
public int lengthOfLongestSubstring2(String s) {
int n = s.length(), ans = 0;
// 存放字符在字符所在最大位置
Map<Character, Integer> map = new HashMap<>();
for (int j = 0, i = 0; j < n; j++) {
if (map.containsKey(s.charAt(j))) {
i = Math.max(map.get(s.charAt(j)), i);
}
ans = Math.max(ans, j - i + 1);
map.put(s.charAt(j), j + 1);
}
return ans;
}
- 思路3:在思路2基础上变动,char字符ascii码128个,用数组代替HashMap,通过字符ascii码当作数组位置
public int lengthOfLongestSubstring3(String s) {
int n = s.length(), ans = 0;
//字符ascii码-数组位置,字符在字符串最大位置-值
int[] index = new int[128];
for (int j = 0, i = 0; j < n; j++) {
i = Math.max(index[s.charAt(j)], i);
ans = Math.max(ans, j - i + 1);
index[s.charAt(j)] = j + 1;
}
return ans;
}