力扣真题:无重复字符的最长子串(三种方法)

这道题我一开始使用了Set加类似滑动窗口的方法,最后解得出来,但效率不尽人意,最后经过几次修改,最终用到是滑动窗口+指针+数组的方式讲效果达到最优,超过近99%的代码。

1、第一版

class Solution {
    public int lengthOfLongestSubstring(String s) {
        //先判断特殊情况
        if (s.equals("")){
            return 0;
        }
           //x[i]记录的是以下标为i字符为最后一个字符时不重复字符字串的长度
          Integer [] x = new Integer[s.length()];
        char[] chars = s.toCharArray();
        for (int i = 0; i < s.length(); i++) {
            int num = 0;
            //记录以下标为i字符为最后一个字符的字串。
            HashSet  aa = new HashSet<>();
            for (int j = i; j >=0; j--) {
                aa.add(chars[j]);
                //当子串里有字符被去重了,就说明不能再往下了。
                if (aa.toArray().length!=++num){
                    num--;
                    break;
                }
            }
            x[i]=num;
        }
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < x.length; i++) {
            if (max

2、第二版

使用了普通的滑动窗口的思路。

class Solution {
    public int lengthOfLongestSubstring(String s) {
        //维护者left和right指针中存在的字符
      HashSet hashSet = new HashSet<>();
        int left = 0;
        int right = 0;
        int max = 0;//最长长度
        while(right

3、第三版

此时不需要维护那个set字串了,直接维护一个数组,记录这上一次这个字符出现的下标,如果出现重复字符,直接将left跳转到这个上一次出现字符的后一个,直接一步到位,不需要其一步步向右移动了。

class Solution {
    public int lengthOfLongestSubstring(String s) {
    //维护一个数组,记录这上一次这个字符出现的下标
       int[] last = new int[128];
        for(int i = 0; i < 128; i++) {
            last[i] = -1;
        }
        int n = s.length();
        int max = 0;
        int left = 0;
        for(int i = 0; i < n; i++) {
            int index = s.charAt(i);
            //直接跳转到上次的出现的下标
            left = Math.max(left, last[index] + 1);
            max   = Math.max(max, i - left + 1);
            //更新最新出现的字符的下标
            last[index] = i;
        }

        return max;
    }
}

你可能感兴趣的:(leetcode,算法,职场和发展)