[路飞]_每天刷leetcode_68(无重复字符的最长子串)

89 阅读1分钟

「这是我参与2022首次更文挑战的第29天,活动详情查看:2022首次更文挑战

无重复字符的最长子串 Longest substring without repeating characters

LeetCode传送门3. 无重复字符的最长子串

题目

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

Given a string s, find the length of the longest substring without repeating characters.

Example:

Input: s = "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.

Input: s = "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.

Input: s = "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3.
Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.

Constraints:

  • 0<=s.length<=51040 <= s.length <= 5 * 10^4
  • s consists of English letters, digits, symbols and spaces.

解题思路

暴力破解

首先我想到的第一种方法就是直接进行两次for循环,然后第一次for为子串的首字母,第二次for为遍历字符串,把每次遍历结果放到res数组中,直到遇到重复的元素,停止遍历,然后取出最长的字串和当前res的长度,并把res设置为空。

代码如下:

function lengthOfLongestSubstring(s: string): number {
    // 暴力破解
    let res = [];
    let max = 0;
    for(let i = 0;i < s.length; i ++) {
        for(let j = i;j < s.length;j ++) {
            if(res.includes(s[j])) {
                max = Math.max(max, res.length);
                res = []
                break;
            } else {
                res.push(s[j])
            }
        }
    }
    return Math.max(max, res.length);
}

时间复杂度

O(n2)O(n^2): 其中n为字符串的长度。

滑动窗口法

​ 上面的解题没有考虑到上一次找到的最长子字符串对下一次遍历产生的影响,因此时间复杂度非常高。我们考虑一下,如果我们从头遍历字符,然后遇到第一个重复的字符,那么我们只要去除掉子字符串重复字符前的字符即可,重复字符后的内容因为已经经过遍历检查我们可以不用再考虑其唯一性,直接使用即可。

根据上面的思考。在编程中我们用如下步骤来完成对应的编程工作

  • 把字符串转换为数组,并遍历
  • 把每次遍历的值进行判断
    • 如果结果数组res中没有该值,证明该值不和前面的值重复,把它放入数组中
    • 如果结果数组res中有该值,证明该值和前面的值重复,先从res数组长度和max直接找到大值,作为max的新值。再从res的头部开始找,直到找到 该重复元素为止,删除数组中重复元素和之前的所有字符。
  • 对max和res的长度进行比较,返回大值,即为我们想要的结果。

代码如下:

function lengthOfLongestSubstring(s: string): number {
    // 滑动窗口法
    const arr = s.split('');
    const res = []
    let max = 0;
    arr.forEach((item, index) => {
        if(res.includes(item)) {
            max = Math.max(max, res.length);
            while(res[0] !==item) {
                res.shift()
            }
            res.shift()
            res.push(item);

        } else {
            res.push(item)
        }
    })
    return Math.max(max, res.length);
};

时间复杂度

O(n): n为字符串的长度

这就是我对本题的解法,如果有疑问或者更好的解答方式,欢迎留言互动。