每天一道算法题

无重复字符的最长子串 leetcode第三题

      首先明确一点,可以直接用set结构判重,那么最简单的方案就是直接暴力破解,双层循环,里层直接循环计算最长子串

// 暴力破解方案
public static int lengthOfLongestSubstring(String s) {
        Set set = new HashSet();
        int maxSize = 0;
        for (int i = 0; i < s.length(); i++) {
            for (int j = i; j < s.length(); j++) {
                boolean notRepeat = set.add(s.charAt(j));
                if (!notRepeat) {
                    maxSize = set.size() > maxSize ? set.size() : maxSize;
                    set.clear();
                    break;
                }
            }
            // 每一轮循环完都清一次
            maxSize = set.size() > maxSize ? set.size() : maxSize;
            // 最大值就不在轮循了
            if (maxSize == s.length()) {
                return maxSize;
            }
            set.clear();
        }
        return maxSize;
    }

      这个方案易于理解,但是明显内层会有很多重复的循环,会重复判断已经存在过的最长不重复子串。那么这里引入时间窗概念,可自行搜索相关概念。

// 时间窗解法
public static int lengthOfLongestSubstringByWindow(String s) {
        Set set = new HashSet();
        int maxSize = 0;

        for (int i = 0; i < s.length(); i++) {
            // 移除掉当前这轮左边的一个
            set.remove(s.charAt(i - 1 < 0 ? i : i - 1));

            // 找到当前这轮的最大序列,注意第二轮开始set里已经有当前窗口的值了,只需要从最远节点开始继续放就行
            for (int j = set.size() + i; j < s.length(); j++) {
                boolean noRepeat = set.add(s.charAt(j));
                if (!noRepeat) {
                    maxSize = set.size() > maxSize ? set.size() : maxSize;
                    break;
                }
            }
            // 有可能一轮循环到完都没有重复的
            maxSize = set.size() > maxSize ? set.size() : maxSize;
            // 全是不重复的就不在轮循了
            if (maxSize == s.length()) {
                return maxSize;
            }
        }
        return maxSize;

    }

你可能感兴趣的:(每天一道算法题)