美文网首页
LeetCode 3. Longest Substring Wi

LeetCode 3. Longest Substring Wi

作者: Sisyphus235 | 来源:发表于2019-04-07 11:20 被阅读0次

Question 3.

Given a string, find the length of the longest substring without repeating characters.

Example 1:

Input: "abcabcbb"
Output: 3 
Explanation: The answer is "abc", with the length of 3. 

Example 2:

Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.

Example 3:

Input: "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3. 
             Note that the answer must be a substring, "pwke" is a subsequence and not a substring.

题目分析

tag

类别是 string。

题目

找到输入字符串中最长的连续无重复字符的子字符串。

思路

这是一道需要照顾全局和局部的题,用变量记录全局的最大长度,同时记录局部符合条件的子字符串情况。

  1. 遍历一遍输入字符串,当前永远记录不重复的子字符串,如果出现重复则从重复字母下一个位置记录子字符串信息。
    以 "abcabcbb" 为例
    只要输入的字符串不为空,则全局最大长度至少等于 1,子字符串为 "",起始位置是 0;
    从 a 开始遍历,子字符串无重复,子字符串增加为 "a",起始位置不变;
    接着是 b,子字符串无重复,子字符串增加为 "ab",起始位置不变;
    接着是 c,子字符串无重复,子字符串增加为 "abc",起始位置不变;
    接着是 a,子字符串重复,当前长度是 3,大于全局最大长度 1,修改全局最大长度为 3,重复字母 a 的位置是 0,修改起始位置为 1,子字符串修改为 "bca";
    接着是 b,子字符串重复,当前长度是 3,等于全局最大长度 3,全局最大长度不变,重复字母 b 的位置是 1,修改起始位置为 2,子字符串修改为 "cab";
    接着是 c,子字符串重复,当前长度是 3,等于全局最大长度 3,全局最大长度不变,重复字母 c 的位置是 2,修改起始位置为 3,子字符串修改为 "abc";
    接着是 b,子字符串重复,当前长度是 3,等于全局最大长度 3,全局最大长度不变,重复字母 b 的位置是 4,修改起始位置为 5,子字符串修改为 "cb";
    接着是 b,子字符串重复,当前长度是 2,小于全局最大长度 3,全局最大长度不变,重复字母 b 的位置是 6,修改起始位置为 7,子字符串修改为 "b";
    遍历结束,全局最大长度是 3。
def longest_substring(s: str) -> int:
    # 处理输入为空和一个字符的情况
    if not s:
        return 0
    if len(s) == 1:
        return 1

    # 初始化全局 long 和子字符串起始位置 start 以及当前内容 cur
    long = 1
    start, cur = 0, s[0]
    for i in range(1, len(s)):
        # 无重复字符则只修改当前子字符串内容
        if s[i] not in cur:
            cur += s[i]
        else:
            # 重复字符则先计算当前子字符串长度,如果大于全局长度则修改
            length = len(cur)
            long = length if length > long else long
            # 计算新的子字符串起始位置和当前内容
            index = cur.index(s[i])
            start += index + 1
            cur = cur[index + 1:] + s[i]
    long = len(cur) if len(cur) > long else long

    return long
  1. 上述思路的主要消耗在于不断拼接字符串,实际上需要判断的是新的字符是不是重复字符,如果是重复字符,其重复位置在哪里。这就启发我们跳出“子字符串”的概念,而是关注背后底层的重复问题,查询字符是否存在最快的方式之一就是哈希,用哈希表记录出现过的字符,以记录是否重复,以及重复的位置

python

def longest_substring_hash(s: str) -> int:
    # 记录出现过的字符和其最后出现的位置
    alpha = {}
    # 记录全局子字符串最大长度
    count = 0
    # 子字符串的起始位置
    first = -1
    for i in range(len(s)):
        # 如果字符重复,且上一个位置是属于当前子字符串,则更新子字符串初始位置
        if s[i] in alpha and alpha[s[i]] > first:
            first = alpha[s[i]]
        # 记录字符的最后出现位置
        alpha[s[i]] = i
        # 判断当前子字符串长度是否大于全局最大长度
        count = max(count, (i - first))
    return count

java

public int longestSubsting(String s) {
    HashMap<Character, Integer> alpha = new HashMap<Character, Integer>();
    int count = 0;
    int first = -1;
    for (int i = 0; i < s.length(); i++) {
        if (alpha.containsKey(s.charAt(i)) && alpha.get(s.charAt(i)) > first) {
            first = alpha.get(s.charAt(i));
        }
        alpha.put(s.charAt(i), i);
        count = Math.max(count, i - first);
    }
    return count;
}

相关文章

网友评论

      本文标题:LeetCode 3. Longest Substring Wi

      本文链接:https://www.haomeiwen.com/subject/dlojiqtx.html