无重复字符的最长子串

165 阅读1分钟
class Solution {
    public int lengthOfLongestSubstring(String s) {
      int[] a = new int[256];
        int[] index = new int[1000];
        int cur = 0;
        int res = 0;
        int left = 0;
        for (int i = 0; i < s.length() ; i++){
            char ch = s.charAt(i);
            if(a[ch] == 0){
                cur++;
                a[ch] = 1;
            }else {
                for (int j = left ; j < index[ch] ; j++){
                    a[s.charAt(j)] = 0;
                    index[s.charAt(j)] = 0;
                    cur--;
                }
              left = index[ch]+1;
            }
            index[ch] = i;
            res = Math.max(res , cur);
        }
        res = Math.max(res, cur);

        return res;
    }
}

解析: 用了两个数组,一个是用来遍历时标记之前是否存在相同的字符,另一个是用来记录遍历时字符的下标,还有一个left记录窗口的最左位置,如果之前出现过相同的字符,则从left开始,到之前字符的下标,重新标记为未访问。

优化:滑动窗口 , 因为字符最大值为255,所以用一个大小为256的整型数组装就够, 用变量left来维护窗口,如果遍历到的字符还没出现过,则窗口大小加一,如果遍历到的字符出现过,但是字符的下标不在窗口内,窗口大小也加一;最后统一对当前字符的窗口下标赋值为遍历下标+1的值(避免下标为0无法分清是否已经遍历)

   class Solution {
    public int lengthOfLongestSubstring(String s) {
       int[] a = new int[256];
       int left = 0 , cur = 0, res = 0;
       for( int i = 0 ; i < s.length(); i++ ){
           char ch = s.charAt( i );
           if( a[ ch ] == 0 || a[ ch ] < left){
               cur++;
           }else{
               cur = i - a[ ch ] + 1;
               left = a[ch];
           }
           a[ ch ] = i + 1;
           res = Math.max( res , cur );
       }
        return res;
    }
}