无重复字符的最长子串-->算法优化与改进

98 阅读2分钟

无重复字符的最长子串

无重复字符的最长子串
题目描述:给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度。

原始思路:将字符串转换为字符数组,遍历数组,将字符存入set集合中,利用set集合不能存储相同的元素来判断是否有相同的字符,同时记录最长数量。

if(s.length()==0){
    return 0;
    }
        char[] c=s.toCharArray();
        Set<Character> set=new HashSet<>();
        int max=0,num=0;
        for (int i = 0; i < c.length; i++) {
            if(set.add(c[i])){
                num++;
                max=Math.max(num,max);
            }else{
                set.clear();
                set.add(c[i]);
                num=1;
                for (int j = i-1; j >=0 ; j--) {
                    if(c[j]!=c[i]){
                        set.add(c[j]);
                        num++;
                    }else {
                        break;
                    }
                }
            }
        }
        return max;

但是这个方法的弊处也很明显,就是虽然set集合可以判断该字符前面是否已经出现过了,但是没办法记录与这个字符相等的上一个字符的位置,还需要反向遍历找到其位置,记录未重复的数量。
于是我就保着学习的念头看了一下题解,果真不出所料,找到了解决办法,代码如下:

        if(s.length()==0){
            return 0;
        }
        char[] c=s.toCharArray();
        int max=0,num=0;
        Map<Character,Integer> m=new HashMap<>();
        for (int i = 0; i < c.length; i++) {
            if(m.containsKey(c[i])){
                num=Math.max(num,m.get(c[i])+1);
            }
            m.put(c[i],i);
            max=Math.max(max,i-num+1);
        }
        return max;

首先,map集合有containsKey()方法可以判断是否已经存在该映射关系,这可以用来判断字符是否重复出现;其次,可以将字符与数组下标关联起来,可以通过映射关系快速的找到其下标,快速的更新未重复的最大长度。
但是这依然不是最优解,我又看到了大神的品论,下面分析一下。我们大家都知道数组是顺序存储结构,优点十分明显,查找非常快,大神也是利用了这一特点引入了一个辅助数组,其下标分别代表字符的ascll码,其存储的值表示所对应得字符在字符串中的下标。不得不说,这一步实在是妙。

int[] x=new int[128];
        for (int i = 0; i < 128; i++) {
            x[i]=-1;
        }
        int max=0,num=0,hasp;
        for (int i = 0; i < s.length(); i++) {
            hasp=s.charAt(i);
            if(x[hasp]!=-1){
                num=Math.max(num,x[hasp]+1);
            }
            max=Math.max(max,i-num+1);
            x[hasp]=i;
        }
        return max;

本来我觉得这道题也就那样,但是它做出来容易,但是这个一步步优化的过程属实是让我震惊了。总的来说这道题对我的帮助很大,一是做题的方法,二是做题的思路都有很大的提升,继续加油。