LeetCode的无重复字符串的最长子串
Leetcode 上的“无重复字符的最长子串”是一个非常经典的问题,涉及到多个计算机科学核心知识点,例如字符串、哈希表和滑动窗口等。在这篇文章中,我们将逐步介绍这些知识点并通过 Java 代码实现这个问题。
- 问题描述
给定一个字符串,找出其中不含重复字符的最长子串的长度。例如,输入 "abcabcbb",其最长子串为 "abc",长度为 3。
- 解题思路
为了解决这个问题,我们可以使用滑动窗口的方法。滑动窗口是一种技巧,用于在字符串或数组上快速查找特定的子数组或子字符串。其基本思想是维护一个移动的窗口,将窗口从字符串的左侧移动到右侧,并在窗口移动时更新解决方案。因此,滑动窗口可以通过线性时间来解决很多问题。
对于这个问题,我们可以使用一个哈希表来存储已经访问的字符和其对应的索引。当发现重复字符时,我们可以将窗口的左侧移动到重复字符的位置的下一个位置,并将哈希表中该字符的索引更新为最新的索引。这样一来,就可以确保滑动窗口中的每个字符都是不重复的。
下面是具体的解题步骤:
- 定义一个哈希表,用于存储每个字符在字符串中最近一次出现的索引值。
- 定义两个指针,即 left 和 right,初始时均指向字符串的第一个字符。
- 用 right 指针遍历整个字符串,同时在哈希表中记录每个字符最近一次出现的索引。
- 如果当前字符已经在哈希表中出现过(即出现重复字符),那么我们需要将 left 指针移动到最近出现该字符的位置的下一个位置,同时更新该字符在哈希表中的索引值。
- 当遍历完整个字符串时,maxLen 变量即为最长子串的长度。
下面是我们用 Java 实现这个算法的代码:
public static int lengthOfLongestSubstring(String s) {
Map<Character, Integer> idxMap = new HashMap<>();
int left = 0, right = 0, maxLen = 0;
while (right < s.length()) {
char c = s.charAt(right);
if (idxMap.containsKey(c)) {
left = Math.max(left, idxMap.get(c) + 1);
}
idxMap.put(c, right);
maxLen = Math.max(maxLen, right - left + 1);
right++;
}
return maxLen;
}
在这段代码中,我们首先定义一个哈希表 idxMap
用于存储每个字符在字符串中最近一次出现的索引值。然后,我们初始化 left 和 right 指针,并遍历整个字符串。在每个字符上,我们首先检查其是否已经在哈希表中出现过。如果是,我们需要将 left 指针移动到最近出现该字符的位置的下一个位置,同时更新该字符在哈希表中的索引值。然后,我们需要更新 maxLen 变量,找到目前为止最长的无重复字符子串的长度。
- 时间复杂度
该算法的时间复杂度为 ,其中 是字符串的长度。
- 空间复杂度
该算法的空间复杂度为 ,其中 是字符串长度, 是字符集大小。
- 示例
下面是几个用例的示例:
- 输入:"abcabcbb",输出:3
- 输入:"bbbbb",输出:1
- 输入:"pwwkew",输出:3
本文介绍了如何使用滑动窗口和哈希表来解决 Leetcode 上的“无重复字符的最长子串”问题,并提供了用 Java 实现该算法的代码。通过掌握这个问题,可以学习到许多计算机科学的核心知识点,例如字符串、哈希表和滑动窗口等。