[LeetCode] 无重复字符的最长子串

Posted longhujing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LeetCode] 无重复字符的最长子串相关的知识,希望对你有一定的参考价值。

无重复字符的最长子串

题目描述

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

示例 1

输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

思路1

先从一个最简单的方法开始,假设i ~ j是一个无重复字符的字串,如果j + 1位置出现了重复的字符,那么就记录这个字符的长度,接着从i + 1开始,直到下一次再次出现重复字符。重复上述操作即可。很明显这个算法需要两层循环,而且时间复杂度为O(n2)

package com.longhujing.leetcode.t0003;

import java.util.Arrays;

/**
 * @author longhujing
 */
public class Solution {

    public int lengthOfLongestSubstring(String s) {
        if (s == null || s.length() == 0) {
            return 0;
        }
        int res = 0;
        boolean[] visited = new boolean[128];
        for (int i = 0; i < s.length(); i++) {
            Arrays.fill(visited, false);
            visited[s.charAt(i)] = true;
            int j = i + 1;
            while (!visited[s.charAt(j)]) {
                visited[s.charAt(j++)] = true;
            }
            res = Math.max(res, j - i);
        }
        return res;
    }

}

思路2

第一种解法的缺陷是重复遍历了字符串,注意是遍历。解释一下:假设子串i ~ j是一个无重复字符的字串,而j + 1位置会导致重复。第一种思路的解法是从i + 1从头开始!但是其实根本没有必要,因为可以确定,从i + 1 ~ j这一段是不可能有重复字符的,所以第一种思路的缺陷在这。假设i ~ j + 1中是k位置和j + 1位置重复了,那么应该舍弃k位置,构造新字串k + 1 ~ j + 1,避免重复无效的搜索。

图片来源: https://www.cnblogs.com/mfrank/p/10472651.html

假设初始状态如下:

技术图片

当to指针到达7号位的时候与6号位重复了,此时应该把from指针放置在6+1即7号位上

技术图片

技术图片

package com.longhujing.leetcode.t0003;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @author longhujing
 */
public class Solution {

    public int lengthOfLongestSubstring(String s) {
        if (s == null || s.length() == 0) {
            return 0;
        }
        int res = 1, start = 0;
        Map<Character, Integer> map = new HashMap<>(128);
        for (int i = 0; i < s.length(); i++) {
            if (map.containsKey(s.charAt(i))) {
                start = Math.max(start, map.get(s.charAt(i)) + 1);
            }
            res = Math.max(res, i - start + 1);
            map.put(s.charAt(i), i);
        }
        return res;
    }

}

以上是关于[LeetCode] 无重复字符的最长子串的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 无重复字符的最长子串

LeetCode——无重复字符的最长子串

leetcode-无重复字符的最长子串

[LeetCode]无重复字符的最长子串

LeetCode 第3题 无重复字符的最长子串

[LeetCode] 无重复字符的最长子串