最長無重複字串/Java/
阿新 • • 發佈:2018-11-06
題目要求:
給定一個字串,請找出其中無重複字元的最長子字串。
樣例
例如,在"abcabcbb"
中,其無重複字元的最長子字串是"abc"
,其長度為 3
。
對於,"bbbbb"
,其無重複字元的最長子字串為"b"
,長度為1
。
O(n) 時間
原題地址:
LeetCode:https://leetcode.com/problems/longest-substring-without-repeating-characters/#/description
LintCode:http://www.lintcode.com/zh-cn/problem/longest-substring-without-repeating-characters/#
分析:
我第一次做這題的時候,是用一種最普通的做法——遍歷兩次,窮舉所有的字串,找出不重複字串,存其長度。最後返回長度的最大值。
但是這樣做的問題是時間複雜度為O(n^2),和題目要求不符,所以在LeetCode和Lintcode上的提交都撲街了。然後意識到應該採用HashMap,但一時也拿不出確切的方法,於是搜尋了一下本題做法。
現在就在這篇部落格貼一下兩種做法吧:
做法一(時間複雜度O(n^2)):
public int lengthOfLongestSubstring(String s) { String res = ""; int temp = 0; ArrayList<Integer> list = new ArrayList<Integer>(); if (s == null || s.length() == 0) { } else if (s.length() == 1) { temp = 1; } else { int i = 0; while (i < s.length() - 1) { int j = 1; while (j <= s.length() - i) { if (isRepetitive(s.substring(i, i + j))) { res = s.substring(i, i + j); temp = Math.max(temp, res.length()); }else{ break; } j++; } i++; } } return temp; }
// 判斷字串是否有重複字元
public static boolean isRepetitive(String s) {
boolean b = true;
if (s.length() > 1) {
for (int i = 1; i < s.length(); i++) {
if (s.substring(0, i).contains(s.substring(i, i + 1))) {
b = false;
break;
}
}
}
return b;
}
做法二(時間複雜度為O(n)):
public int lengthOfLongestSubstring(String s) {
int temp = 0;
if (s == null || s.length() == 0) {
} else {
Map<Character, Integer> myMap = new HashMap<Character, Integer>();
// 用以儲存不重複字串的長度
int[] strlength = new int[s.length() + 1];
// 用字元陣列表示字串
char[] str = s.toCharArray();
for (int i = 0; i < str.length; i++) {
Integer lastPosOfChar = myMap.get(str[i]);
if (lastPosOfChar == null) {
// 更新最長無重複子串的長度
strlength[i] = i == 0 ? 1 : strlength[i - 1] + 1;
// 果map新增該字元和位置
myMap.put(str[i], i);
} else {
int aPos = lastPosOfChar + 1;
int unRepeatLen = strlength[i - 1];
int bPos = i - unRepeatLen;
if (aPos >= bPos) {
// 當前位置的最長無重複子串長度
strlength[i] = i - aPos + 1;
} else {
// 當前位置的最長無重複子串長度
strlength[i] = i - bPos + 1;
}
// 跟新當前字元出現的位置
myMap.put(str[i], i);
}
}
for (int i : strlength) {
temp = Math.max(temp, i);
}
}
return temp;
}
總結:Map大法好,應當努力學習一個。