leetcode 力扣 3 无重复字符的最长子串

91 阅读1分钟

滑动窗口

算法思想:

  • 使用双指针leftright组成一个窗口,向右滑动;
  • 使用布尔数组模拟哈希集,如果right指向的字符已经在哈希集中存在,则使left一直往右移动,移除这些元素,直到该字符消失 。
public int lengthOfLongestSubstring(String s) {
            char[] charArray = s.toCharArray();
            boolean[] has = new boolean[128];
            int left = 0, right = 0;
            int ans = 0;

            for (right = 0; right < s.length(); right++) {
                char c = charArray[right];

                while (has[c]) {
                    has[charArray[left++]] = false;
                }

                has[c] = true;

                ans = Math.max(ans, right - left + 1);
            }

            return ans;
        }

把字符串转换为字符数组,方便检索,使用布尔数组检查当前窗口的字符是否是唯一的,滑动窗口的核心代码是这行:

while (has[c]) {
    has[charArray[left++]] = false;
}

lc3.jpeg

借用上图,当右指针移动到右边的a,左指针会把左边的a剔除(charArray[0]就是ahas['a'] = false),更新left = 1,并把a重新设置为true。如果写成下面那样会导致死循环:

while (has[c]) {
       c = charArray[++left];
}

当右指针移动到右边的b,左指针会把左边的b剔除,直到剔除c,此时 ans = 6 - 3 + 1 = 4,也就是dabc,以此类推。。。