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

题目描述

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

示例:

  • 输入: s = "abcabcbb"

  • 输出: 3

  • 解释: 无重复字符的最长子串是 "abc",其长度为 3。

  • 输入: s = "bbbbb"

  • 输出: 1

  • 解释: 无重复字符的最长子串是 "b",其长度为 1。

  • 输入: s = "pwwkew"

  • 输出: 3

  • 解释: 无重复字符的最长子串是 "wke",其长度为 3。

解题思路

使用滑动窗口算法来解决这个问题。滑动窗口的基本思路是使用两个指针来标记一个窗口的开始和结束位置,然后不断调整这两个指针来找到符合条件的最长子串。

具体步骤如下:
  1. 初始化变量:

    • startend 两个指针分别表示当前窗口的起始和结束位置。
    • maxLength 表示找到的最长无重复字符子串的长度。
    • 使用一个哈希表或数组 charIndex 来记录每个字符最后出现的位置。
  2. 滑动窗口操作:

    • 遍历字符串中的每一个字符,使用 end 指针逐个扫描。
    • 如果当前字符已经在 charIndex 中并且它的索引值大于等于 start,这意味着出现了重复字符,此时需要更新 start 位置为当前字符上次出现位置的下一个位置。
    • 无论是否出现重复字符,都要更新当前字符在 charIndex 中的索引值,并计算当前无重复子串的长度,然后更新 maxLength
  3. 返回结果:

    • 最终返回 maxLength,即为最长无重复子串的长度。

代码实现

C 实现
#include <stdio.h>
#include <string.h>

int lengthOfLongestSubstring(char * s) {
    int charIndex[128] = {0}; // ASCII 字符集大小
    int maxLength = 0;
    int start = 0;

    for (int end = 0; s[end] != '\\0'; end++) {
        if (charIndex[s[end]] > start) {
            start = charIndex[s[end]];
        }
        charIndex[s[end]] = end + 1; // 更新字符的最新索引
        int currentLength = end - start + 1;
        if (currentLength > maxLength) {
            maxLength = currentLength;
        }
    }

    return maxLength;
}

int main() {
    char s[] = "abcabcbb";
    printf("Longest substring length: %d\\n", lengthOfLongestSubstring(s));
    return 0;
}
Java 实现
import java.util.HashMap;

class Solution {
    public int lengthOfLongestSubstring(String s) {
        HashMap<Character, Integer> charIndex = new HashMap<>();
        int maxLength = 0;
        int start = 0;

        for (int end = 0; end < s.length(); end++) {
            char currentChar = s.charAt(end);
            if (charIndex.containsKey(currentChar)) {
                start = Math.max(start, charIndex.get(currentChar) + 1);
            }
            charIndex.put(currentChar, end);
            maxLength = Math.max(maxLength, end - start + 1);
        }

        return maxLength;
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        String s = "abcabcbb";
        System.out.println("Longest substring length: " + solution.lengthOfLongestSubstring(s));
    }
}
Python 实现
def length_of_longest_substring(s: str) -> int:
    char_index = {}
    max_length = 0
    start = 0

    for end in range(len(s)):
        if s[end] in char_index:
            start = max(start, char_index[s[end]] + 1)
        char_index[s[end]] = end
        max_length = max(max_length, end - start + 1)

    return max_length

# 测试
s = "abcabcbb"
print("Longest substring length:", length_of_longest_substring(s))

时间复杂度

该算法的时间复杂度为 On,其中 n 是字符串的长度。因为每个字符在最坏情况下被遍历两次,一次由 end 指针,一次由 start 指针。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰魄雕狼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值