題目:
給定一個字符串,請你找出其中不含有重複字符的 最長子串 的長度。
示例 1:
輸入: "abcabcbb"
輸出: 3
解釋: 因爲無重複字符的最長子串是 "abc",所以其
長度爲 3。
示例 2:
輸入: "bbbbb"
輸出: 1
解釋: 因爲無重複字符的最長子串是 "b"
,所以其長度爲 1。
示例 3:
輸入: "pwwkew" 輸出: 3 解釋: 因爲無重複字符的最長子串是"wke"
,所以其長度爲 3。 請注意,你的答案必須是 子串 的長度,"pwke"
是一個子序列,不是子串。
解題思路:遍歷數組,並將遍歷的元素加入map(利用map的keyset中不含重複元素的特性),若出現重複key則計算長度,然後迴歸到首個重複元素的下標,如序列"psadcaa",在下標5的地方檢測到重複,則將遍歷序號從第一個a(即下標2)之後開始。直到遍歷完整個數組。
代碼:
public static int lengthOfLongestSubstring(String s) {
if(s.equals("")) {
return 0;
}
int maxlength = 1;
char[] a = s.toCharArray();
HashMap<Character,Integer> map = new HashMap<>(s.length());
for(int i=0;i<a.length;i++) {
if(!map.containsKey(a[i])) {
map.put(a[i],i);
}else {
if(map.size()>maxlength) {
maxlength = map.size();
}
i = map.get(a[i]);
map.clear();
}
}
if(map.size()>maxlength) {
maxlength = map.size();
}
return maxlength;
}
算法改進:不採用HashMap的個數來確定子串長度,而是 使用滑動窗口的方式來確定子串長度,即定義一組起始序號和結束序號begin,end來標誌子串,避免了大量的map.clear()操作。
代碼:
public static int lengthOfLongestSubstring(String s) {
if(s.equals("")) {
return 0;
}
int maxlength = 1;
int begin=0,end=1;
char[] a = s.toCharArray();
HashMap<Character,Integer> map = new HashMap<>(s.length());
for(int i=0;i<a.length;i++) {
if(map.containsKey(a[i])&&map.get(a[i])>=begin) {
if((end - begin)>maxlength) {
maxlength = end - begin;
}
begin = map.get(a[i]) + 1;
}
map.put(a[i],i);
end = i + 1;
}
maxlength = Math.max((end - begin), maxlength);
return maxlength;
}