Given a string, find the length of the longest substring without repeating characters.
Examples:
Given “abcabcbb”, the answer is “abc”, which the length is 3.
Given “bbbbb”, the answer is “b”, with the length of 1.
Given “pwwkew”, the answer is “wke”, with the length of 3. Note that the answer must be a substring, “pwke” is a subsequence and not a substring.
这个题目我昨晚上一下子没有做出来,看了别人的参考之后,早上来到实验室搞定了,应该算是掌握了吧,下面是我自己贴的代码,仅供参考哈。
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) {
return 0;
}
HashSet<Character> set = new HashSet<Character>();
int leftPosition = 0, max = 0;
for (int i = 0; i < s.length(); i++) {
if (set.contains(s.charAt(i))) {
while (leftPosition < i
&& s.charAt(leftPosition) != s.charAt(i)) {
set.remove(s.charAt(leftPosition));
leftPosition++;
}
leftPosition++;
} else {
set.add(s.charAt(i));
max = Math.max(max, i - leftPosition + 1);
}
}
return max;
}
第一次提交超时了,第二次提交通过了。。提交通过之后会有机会查看别人写的优秀代码,这个提醒大家千万别忘记了。下面来看几种,第一种貌似是超时了。
Approach #1 Brute Force [Time Limit Exceeded]
public class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
int ans = 0;
for (int i = 0; i < n; i++)
for (int j = i + 1; j <= n; j++)
if (allUnique(s, i, j)) ans = Math.max(ans, j - i);
return ans;
}
public boolean allUnique(String s, int start, int end) {
Set<Character> set = new HashSet<>();
for (int i = start; i < end; i++) {
Character ch = s.charAt(i);
if (set.contains(ch)) return false;
set.add(ch);
}
return true;
}
}
Approach #2 Sliding Window [Accepted]
public class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
Set<Character> set = new HashSet<>();
int ans = 0, i = 0, j = 0;
while (i < n && j < n) {
// try to extend the range [i, j]
if (!set.contains(s.charAt(j))){
set.add(s.charAt(j++));
ans = Math.max(ans, j - i);
}
else {
set.remove(s.charAt(i++));
}
}
return ans;
}
}
Approach #3 Sliding Window Optimized [Accepted]
public class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length(), 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 < 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;
}
}
最后介绍一种典型的空间换时间的算法。
/**
* int[26] for Letters 'a' - 'z' or 'A' - 'Z'
int[128] for ASCII
int[256] for Extended ASCII
* @param s
* @return
*/
public int lengthOfLongestSubstring2(String s) {
int n = s.length(), ans = 0;
int[] index = new int[128]; // current index of character
// try to extend the range [i, j]
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;
}