問題:
給定一個字符串,找出不含有重復字符的最長子串的長度。
示例 1:
輸入: "abcabcbb"
輸出: 3
解釋: 無重復字符的最長子串是 "abc",其長度為 3。
示例 2:
輸入: "bbbbb"
輸出: 1
解釋: 無重復字符的最長子串是 "b",其長度為 1。
示例 3:
輸入: "pwwkew"
輸出: 3
解釋: 無重復字符的最長子串是 "wke",其長度為 3。
請注意,答案必須是一個子串,"pwke" 是一個子序列 而不是子串。
思路
- 思路1:兩循環(huán)來獲取所有子串,通過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:一個循環(huán),通過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個,用數(shù)組代替HashMap,通過字符ascii碼當作數(shù)組位置
public int lengthOfLongestSubstring3(String s) {
int n = s.length(), ans = 0;
//字符ascii碼-數(shù)組位置,字符在字符串最大位置-值
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;
}