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.
Solution: First, let's assume that the start in the maximum subarray when we get to the I-1 position has been maintained, then at the i-1 position, we need to determine whether the i-th character is a duplicate character, and if so, start moves to the back of the first identical character after the start; if not, then add hashset, then update that max, and most importantly. Then go back to max.
class Solution {
public int lengthOfLongestSubstring(String s) {
//special case
if (s.length() <= 1) return s.length();
//base case
HashSet<Character> set = new HashSet<>();
int start = 0, max = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (set.contains(c)) {
for (int j = start; j < i; j++) {
char cc = s.charAt(j);
if ( cc== c) {
start = j + 1;
break;
} else {
set.remove(cc);
}
}
} else {
set.add(c);
if (i - start + 1 > max) {
max = i - start + 1;
}
}
}
return max;
}
}
See the hashmap with Character as the key, no brains use arrays!!! Because Character's range is fixed, it can be directly replaced by an array. The following code is more efficient.
public int lengthOfLongestSubstring(String s) {
//special case
if (s.length() <= 1) return s.length();
//base case
int[] index = new int[256];
int max = 0, start = 0;
//Since 0 can mean index = 0 here, we initialize index with -1.
for (int i = 0; i < 256; i++) {
index[i] = -1;
}
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (index[c] == -1) {
index[c] = i;
max = Math.max(max, i - start + 1);
} else {
for (int j = start; j < index[c]; j++) {
index[s.charAt(j)] = -1;
}
start = index[c] + 1;
index[c] = i;
}
}
return max;
}