Leetcode刷题系列:无重复字符的最长子串

486 阅读2分钟

这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战

题目

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

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/lo…

示例:

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

示例 2:

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

示例 3:

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

实现方案1 :暴利破解

实现步骤:

  1. 定义变量 maxLength 表示最大长度
  2. 使用双指针截取不包含重复的字符串
  3. 计算子串长度,保留较大值到 maxLength
public int lengthOfLongestSubstring(String s) {
    int len = s.length();
    if (s == null || s.length() == 0) {
        return 0;
    }
    int maxLength = 1;
    for (int start = 0; start < len; start++) {
        for (int end = start + 1; end < len; end++) {
            String subStr = s.substring(start, end);
            if (subStr.indexOf(s.charAt(end)) != -1) {
                break;
            }
            int subLen = end - start + 1;
            if (subLen > maxLength) {
                maxLength = subLen;
            }
        }
    }
    return maxLength;
}

实现方案2 :哈希表 + 双指针

实现逻辑:

  • 定义哈希表,临时存储子串字符和查重
  • 遍历字符串,通过双指针循环定位子串
    • 判断右指针数据是否在哈希表中存在
      • 否:记录到哈希表,并向右移动,并计算长度
      • 是:删除哈希表中的元素,并移动左指针
    • 最后再次重复检查右指针元素是否还存在
  • 每次计算子串长度,比较并保留最大值
int hash(char key) {
    return key;
}

public int lengthOfLongestSubstring3(String s) {
    int len;
    // 源字符串长度
    if (s == null || (len = s.length()) == 0) {
        return 0;
    }
    // 最长不重复子串的长度
    int res = 0;
    // 子串最左端字符索引
    int left = 0;
    // 子串最右端字符索引
    int right = 0;

    // 1.定义哈希表,支持ASCII码表的全部字符
    char[] chs = new char[128];
    // 2.遍历字符串的所有字符
    while (right < len) {
        char rightChar = s.charAt(right); // 右指针字符
        char c = chs[(chs.length - 1) & hash(rightChar)]; // hash算法
        if (rightChar != c) { // 未重复出现
            // 2.1.双指针定位子串索引:右指针自增
            right++;
            // 将不重复字符记录到哈希表中
            chs[(chs.length - 1) & hash(rightChar)] = rightChar;
            // 3.每次记录子串长度,并计算最大值
            int size = right - left; // 每个不重复子串的长度
            res = res > size ? res : size;
        } else { // 重复出现
            // 2.2.双指针定位子串索引:左指针自增。从哈希表中移出最左侧字符:赋默认值
            char leftChar = s.charAt(left++);
            chs[(chs.length - 1) & hash(leftChar)] = '\u0000';
        }
    }
    return res;
}

github 地址

案例地址

其他

广大 倔友 大佬们,如果看了文章!!! 请不要吝啬你们的点评!!! 如果有更好的解题思路 或者 我解题中不足的地方,文章书写不行的地方,希望大家能 给我评论指点一二!! 感谢大家!!