目录

  • 1.题目以及测试用例:
  • 2.解题思路:
  • 3.代码实现:
  • 4.复杂度说明:


1.题目以及测试用例:

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

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

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

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

请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。*

2.解题思路:

解析:

本题使用滑动窗口的思想可以进行解决

首先,定义三个变量:left表示当前滑动窗口的左边界,初值为0maxLen表示最长不重复子串的长度,初值为0map是一个Map对象,用来记录字符和字符对应的下标。
然后,通过一个循环遍历字符串s中的每个字符。在每次循环中,首先判断当前字符s[i]是否在map中存在,并且它的下标大于等于left。如果满足条件,则将left移动到s[i]上次出现的下标的下一个位置,确保滑动窗口中不包含重复的字符。
接下来,更新maps[i]的值为当前下标i,表示最近一次出现s[i]的位置。然后,计算当前滑动窗口的长度i - left + 1,并与maxLen比较,取较大值作为新的maxLen

最后,循环结束后,返回maxLen作为结果,即最长不重复子串的长度。


3.代码实现:

代码:

/**
 * @param {string} s
 * @return {number}
 */
var lengthOfLongestSubstring = function(s) {
    let left = 0;
    let maxLen = 0;
    let map = new Map();
    for (let i = 0; i < s.length; i++) {
        if (map.has(s[i]) && map.get(s[i]) >= left) {
            left = map.get(s[i]) + 1;
        }
        map.set(s[i], i);
        maxLen = Math.max(maxLen, i - left + 1);
    }
    return maxLen;
};

4.复杂度说明:

时间复杂度和空间复杂度解析:

时间复杂度是O(n),其中n是输入字符串的长度。这是因为代码中使用了一个循环来遍历字符串中的每个字符。

在循环中,大部分操作的时间复杂度都是O(1),例如对map的操作、取最大值、更新maxLen等。这些操作的时间复杂度不随输入规模增大而改变。

因此,循环的时间复杂度主要取决于字符串的长度n。每个字符都会被遍历一次,所以循环的时间复杂度是O(n)

同时,代码中使用了一个map来记录字符和字符对应的下标,所以空间复杂度是O(k),其中k是字符串中不重复字符的个数。在最坏的情况下,字符串中的每个字符都不相同,因此k最多为n。所以空间复杂度可以近似看作是O(n)