题目:
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.
思路:
维护一个窗口,这个窗口里的字符是当前考察的不重复子串,左边界是maxindex,右边界为i,imax数组表示遍历到i时,以i为结束的最长不重复子串。
遍历一遍,对每个字符,都有两个选择:
①如果它不与窗口内的字符重复,那么将它加入到这个不重复子串,构成新的窗口(待考察不重复子串)左边界不变,右边界向后挪一个,imax[i]=imax[i-1]+1;
②如果它与窗口内的字符重复,那么窗口的左边界向右挪变为“”被重复的字符“”的下一个字符,右边界向右挪一个。维护新窗口可以重新new一个hashset,把[原set.get(s.charAt(i)+1,i]的字符放进新set,也可以从原set中remove掉[maxindexpre,set.get(s.charAt(i))],再put进set.put(s.charAt(i), i)。
用数组或hashmap去维护当前这个窗口,用来查验第i个字符是否与窗口内的字符重复。
时间复杂度为O(n)
class Solution {
public int lengthOfLongestSubstring(String s) {
if(s.length()==0||s.length()==1)
return s.length();
HashMap<Character,Integer> set =new HashMap<Character,Integer>();
int [] imax =new int[s.length()];
int max=1;
int maxindex=0;
imax[0]=1;
set.put(s.charAt(0),0);
for(int i=1;i<s.length();i++){
if(!set.containsKey(s.charAt(i))){
set.put(s.charAt(i),i);
imax[i]=imax[i-1]+1;
max=Math.max(imax[i],max);
}
else{
imax[i]=i-set.get(s.charAt(i));
int maxindexpre=maxindex;//这下面的处理为了移除set中“过期”的字符
maxindex=set.get(s.charAt(i))+1;
while(maxindexpre<maxindex) {
set.remove(s.charAt(maxindexpre));
maxindexpre++;
}
set.put(s.charAt(i), i);
}
}
return max;
}
}
类似题目:思路类似于最大子序列的和