返回
如何找到字符串中的无重复字符最长子串:JS、TS和Python代码解析
前端
2023-11-22 12:27:52
算法概述
无重复字符最长子串问题可以为:给定一个字符串,请找出其中不含有重复字符的最长子串。例如,对于字符串 "abcabcbb",无重复字符的最长子串是 "abc",其长度为 3;对于字符串 "bbbbbbb",无重复字符的最长子串是 "b",其长度为 1。
为了解决这个问题,我们可以使用滑动窗口算法。该算法的基本思想是使用两个指针来定义一个窗口,然后在字符串中移动窗口。窗口中的字符必须不重复,并且窗口的大小应该是最大的。
下面是滑动窗口算法的具体步骤:
- 初始化两个指针,分别指向字符串的开始和结束。
- 在窗口中查找重复字符。
- 如果窗口中存在重复字符,则将开始指针向右移动一个字符,然后重复步骤2。
- 如果窗口中不存在重复字符,则将结束指针向右移动一个字符,然后重复步骤2。
- 重复步骤2到4,直到结束指针到达字符串的结尾。
- 记录窗口的最大长度。
实现代码
JavaScript
/**
* 找到字符串中不含有重复字符的最长子串
* @param {string} str 输入字符串
* @return {number} 最长子串的长度
*/
const lengthOfLongestSubstring = (str) => {
// 定义滑动窗口的开始和结束指针
let start = 0;
let end = 0;
// 定义一个哈希表来存储字符及其最近出现的位置
const charMap = {};
// 定义无重复字符的最长子串的长度
let maxLength = 0;
// 遍历字符串
while (end < str.length) {
// 如果当前字符不在哈希表中,则将其添加到哈希表中并更新结束指针
if (!charMap[str[end]]) {
charMap[str[end]] = end;
end++;
} else {
// 如果当前字符在哈希表中,则更新开始指针并更新哈希表
start = Math.max(start, charMap[str[end]] + 1);
charMap[str[end]] = end;
end++;
}
// 更新无重复字符的最长子串的长度
maxLength = Math.max(maxLength, end - start);
}
// 返回无重复字符的最长子串的长度
return maxLength;
};
TypeScript
/**
* 找到字符串中不含有重复字符的最长子串
* @param {string} str 输入字符串
* @return {number} 最长子串的长度
*/
const lengthOfLongestSubstring = (str: string): number => {
// 定义滑动窗口的开始和结束指针
let start = 0;
let end = 0;
// 定义一个哈希表来存储字符及其最近出现的位置
const charMap: { [key: string]: number } = {};
// 定义无重复字符的最长子串的长度
let maxLength = 0;
// 遍历字符串
while (end < str.length) {
// 如果当前字符不在哈希表中,则将其添加到哈希表中并更新结束指针
if (!charMap[str[end]]) {
charMap[str[end]] = end;
end++;
} else {
// 如果当前字符在哈希表中,则更新开始指针并更新哈希表
start = Math.max(start, charMap[str[end]] + 1);
charMap[str[end]] = end;
end++;
}
// 更新无重复字符的最长子串的长度
maxLength = Math.max(maxLength, end - start);
}
// 返回无重复字符的最长子串的长度
return maxLength;
};
Python
def length_of_longest_substring(str):
"""
找到字符串中不含有重复字符的最长子串
:param str: 输入字符串
:return: 最长子串的长度
"""
# 定义滑动窗口的开始和结束指针
start = 0
end = 0
# 定义一个哈希表来存储字符及其最近出现的位置
char_map = {}
# 定义无重复字符的最长子串的长度
max_length = 0
# 遍历字符串
while end < len(str):
# 如果当前字符不在哈希表中,则将其添加到哈希表中并更新结束指针
if str[end] not in char_map:
char_map[str[end]] = end
end += 1
else:
# 如果当前字符在哈希表中,则更新开始指针并更新哈希表
start = max(start, char_map[str[end]] + 1)
char_map[str[end]] = end
end += 1
# 更新无重复字符的最长子串的长度
max_length = max(max_length, end - start)
# 返回无重复字符的最长子串的长度
return max_length
复杂度分析
滑动窗口算法的时间复杂度为 O(n),其中 n 是字符串的长度。这是因为算法只遍历字符串一次,并且在每次遍历中只执行常数次操作。
滑动窗口算法的空间复杂度为 O(min(n, k)),其中 k 是无重复字符的最长子串的长度。这是因为哈希表最多存储 k 个字符及其最近出现的位置。
扩展应用
滑动窗口算法可以用来解决许多其他问题,例如:
- 寻找字符串中的最长回文子串
- 寻找字符串中的最长重复子字符串
- 寻找字符串中的最长公共子串
- 寻找字符串中的最长子数组之和
滑动窗口算法是一个非常有用的算法,掌握它可以帮助我们解决许多实际问题。