Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1.
分析:见到非重复,应该想到Hash。
这题可以用HashMap来存放字符和对应下标的关系,然后遍历,如果遇见重复的,就可以直接找到上一个重复字符的出现位置,把之前的全部清0.
怎么把之前的全部清除呢?
这里用一个start变量,记录当前字符串开始的位置,如果碰见重复的,则从start开始,从HashMap里移除现有值,直到重复的字符,就实现了对之前元素的清除。
public class Solution {
public int lengthOfLongestSubstring(String s) {
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
int max = 0;
int start = 0;
for(int i=0; i<s.length(); i++){
char c = s.charAt(i);
if(map.containsKey(c)){
max = Math.max(max, map.size());
for(int j=start; j<i; j++){
if(s.charAt(j) == c){
start = j+1;
break;
}
map.remove(s.charAt(j));
}
}else{
map.put(c, i);
}
}
return Math.max(max, map.size());
}
}
下面解法,用的是桶排得思想,假设全部为ASCII字符,用一个长256的数组当字典,原理和Hash是一样的,局限是假定字符都是ASCII的。
public class Solution {
public int lengthOfLongestSubstring(String s) {
boolean[] flag = new boolean[256];
int result=0;
int j=0;
char[] arr = s.toCharArray();
for(int i=0; i<arr.length; i++){
char c = arr[i];
if(flag[c]){//如果为真,说明已经存过
result = Math.max(result, i-j);
for(int k=j; k<i; k++){
if(arr[k]==c){//找到c的下标,更新j
j=k+1;
break;
}
flag[arr[k]]=false;
}
}else
flag[c]=true;
}
result = Math.max(arr.length-j,result);
return result;
}
}