题目描述(中等)

原题链接

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

示例

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

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

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

解决方法

滑动窗口

我们使用两个指针表示字符串中的某个子串(或窗口)的左右边界,其中左指针代表着上文中「枚举子串的起始位置」,而右指针即为上文中的 $r_k$

在每一步的操作中,我们会将左指针向右移动一格,表示 我们开始枚举下一个字符作为起始位置,然后我们可以不断地向右移动右指针,但需要保证这两个指针对应的子串中没有重复的字符。在移动结束后,这个子串就对应着 以左指针开始的,不包含重复字符的最长子串。我们记录下这个子串的长度;

在枚举结束后,我们找到的最长的子串的长度即为答案。

在上面的流程中,我们还需要使用一种数据结构来判断 是否有重复的字符,常用的数据结构为哈希集合(即 C++ 中的 std::unordered_setJava 中的 HashSetPython 中的 set, JavaScript 中的 Set)。在左指针向右移动的时候,我们从哈希集合中移除一个字符,在右指针向右移动的时候,我们往哈希集合中添加一个字符。

代码:

var twoSum = function(nums, target) {
let len = nums.length;
for(let i=0;i<len;i++) {
for(let j=0;j<len;j++) {
if(nums[i]+nums[j]==target&&i!=j) {
return [i,j]
}
}
}
return false;
};

复杂度分析

  • 时间复杂度:O(N)O(N),其中 NN 是字符串的长度。左指针和右指针分别会遍历整个字符串一次。

  • 空间复杂度:O(|\Sigma|)O(∣Σ∣),其中 \SigmaΣ 表示字符集(即字符串中可以出现的字符),|\Sigma|∣Σ∣ 表示字符集的大小。在本题中没有明确说明字符集,因此可以默认为所有 ASCII 码在 [0, 128)[0,128) 内的字符,即 |\Sigma| = 128∣Σ∣=128。我们需要用到哈希集合来存储出现过的字符,而字符最多有 |\Sigma|∣Σ∣ 个,因此空间复杂度为 O(|\Sigma|)O(∣Σ∣)。