无重复字符的最长子字符串——Java实现
2023-09-02 21:27:20
引言
在计算机科学中,“无重复字符的最长子字符串”问题是一个经典的面试题。给定一个字符串,我们需要找到其中不包含重复字符的最长子字符串。例如,对于字符串“abcabcbb”,最长子字符串是“abc”,因为它不包含任何重复字符,长度为3。
解决方案一:滑动窗口
滑动窗口算法是一种常用的字符串处理算法,可以用来高效地解决无重复字符的最长子字符串问题。该算法的基本思想是使用一个窗口在字符串中滑动,并记录窗口中出现的字符。当窗口中出现重复字符时,窗口向右移动一位,继续扫描剩余的字符串。同时,我们不断更新无重复字符的最长子字符串的长度。
public class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
Set<Character> set = new HashSet<>();
int maxLen = 0;
int left = 0;
for (int right = 0; right < n; right++) {
char c = s.charAt(right);
while (set.contains(c)) {
set.remove(s.charAt(left));
left++;
}
set.add(c);
maxLen = Math.max(maxLen, right - left + 1);
}
return maxLen;
}
}
在上面的Java代码中,我们使用了一个HashSet来存储窗口中出现的字符。当窗口中出现重复字符时,我们将窗口向右移动一位,并不断更新无重复字符的最长子字符串的长度。这个算法的时间复杂度为O(n),空间复杂度为O(n),其中n是字符串的长度。
解决方案二:改进的滑动窗口
我们可以对滑动窗口算法进行改进,使用一个数组来存储窗口中出现的字符的最后出现位置。这样,当窗口中出现重复字符时,我们可以直接跳到重复字符的最后出现位置,而不用从头开始扫描整个窗口。
public class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
int[] lastIndex = new int[128];
int maxLen = 0;
int left = 0;
for (int right = 0; right < n; right++) {
char c = s.charAt(right);
if (lastIndex[c] > 0) {
left = Math.max(left, lastIndex[c]);
}
lastIndex[c] = right + 1;
maxLen = Math.max(maxLen, right - left + 1);
}
return maxLen;
}
}
在上面的Java代码中,我们使用了一个数组lastIndex来存储窗口中出现的字符的最后出现位置。当窗口中出现重复字符时,我们将窗口向右移动到重复字符的最后出现位置,并不断更新无重复字符的最长子字符串的长度。这个算法的时间复杂度为O(n),空间复杂度为O(n),其中n是字符串的长度。
结语
在本文中,我们介绍了两种解决无重复字符的最长子字符串问题的Java实现。滑动窗口算法是一种常用的字符串处理算法,可以用来高效地解决这个问题。我们可以对滑动窗口算法进行改进,使用一个数组来存储窗口中出现的字符的最后出现位置,从而进一步提高算法的效率。这些算法的时间复杂度都是O(n),空间复杂度都是O(n),其中n是字符串的长度。