题目:

  给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

题解:

  看到判断是否重复,我们首先应该想到Set,因为Set存储的是无重复的、无排序的元素。假如看到统计元素的个数,首先应该想到Map,只有使用了对的数据结构,才能使得我们的代码的运行效率更高,时间复杂度更低。在空间和时间的取舍上,我们一贯的思维是空间换时间,毕竟韶光易逝不复返,但机器硬件我们是可以堆砌出来的。

  在计算器网络中,滑动窗口机制相信我们都有所了解,它是TCP/IP的可靠传输的保证机制。子串的含义是字符之间的位置要是连续的、有序的(相对位置不变),这恰恰符合滑动窗口的思想。所以,接下里我们就来是滑动窗口算法来解决此题。

  1.使用Set来判断字符是否有重复

  2.假如字符有重复,那么就将窗口的左边界移到到重复字符的下一个位置,这样就能保证窗口中的字符构成的是无重复字符的、有序的子串。下面上代码:

Java版本

public int lengthOfLongestSubstring(String s) {
        if(s == null || s.length() == 0) return 0;
        
        int maxLen = 0;
        for(int i=0;i<s.length();i++){
            //滑动窗口 Set
            Set<Character> set = new HashSet<Character>();//判断是否有重复
            set.add(s.charAt(i));
            for(int j=i+1;j<s.length();j++){
                char c= s.charAt(j);
                if(!set.contains(c)) set.add(c);
                else{//有重复的元素
                    maxLen = Math.max(maxLen,set.size());
                    //删除重复的元素,即将窗口的左边界移到到重复字符的下一个位置
                    while(set.contains(c)){
                        set.remove(s.charAt(i++));
                    }
                    set.add(c);
                }
            }
            maxLen = Math.max(maxLen,set.size());
        }
        return maxLen;

    }

JS版本

var lengthOfLongestSubstring = function(s){
    if(!s || s.length ==0){
        return 0;
    }
    var j =0,i = 0,maxLen = 0;
    var set = new Set();
    for(i;i < s.length;i ++){
        if(!set.has(s[i])){
            set.add(s[i]);
            maxLen = Math.max(maxLen,set.size);
        }else{//将窗口的左边界移到到重复字符的下一个位置
            while(set.has(s[i])){
                set.delete(s[j]);
                j++;
            }
            set.add(s[i]);
        }
    }
}

 

  

  

posted on 2021-02-19 15:13  李白菜  阅读(129)  评论(0编辑  收藏  举报