leetcode : 3无重复字符最长子串(中等)

705 阅读3分钟

题目描述:

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

示例 1:

输入: s = "abcabcbb"

输出: 3

解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: s = "bbbbb"

输出: 1

解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: s = "pwwkew"

输出: 3

解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。   请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

示例 4:

输入: s = ""

输出: 0  

提示:

  • 0 <= s.length <= 5 * 104

  • s 由英文字母、数字、符号和空格组成

力扣(LeetCode) 链接:leetcode-cn.com/problems/lo…

思路:

我们看到题目时首先可以抓住两个最核心的要求

1.要找传入字符串中最长的一个子串

2.这个最长子串无重复字符

我们可以抓住这两个核心点来分析这个问题,解决这道题目,我们可以采用滑动窗口思想,滑动窗口的思想可以很好的处理这两个核心点

这里先介绍一下什么是滑动窗口思想,正如其名字,它是一个可以左右滑动的窗口(队列),当队列中的元素增加或者删除时,我们将窗口进行移动,就如这道题目,如果设定一个字符串 juejin,进入队列的要求为非重复字符,那么这里首先能够进去的字符串就为 jue, 然后继续传 j ,由于前面队列已经有了 j ,这时就会无法进入,那么为了进入队列,我们就要将队列中与其相同的字符及其之前的字符进行删除,所以这时候就需要移动窗口,我们将窗口进行右移,将左边的元素 j 进行移除,并且在每次传入字符操作时进行最大值的记录,这样不断进行 进入移动 的操作,就能将字符串中最长的无重复子串找出来了

所以,通过滑动窗口思想既用移动操作解决了无重复的问题,又用最大值记录操作又解决了最长子串问题

那么,下面来让我们看一下代码吧

8FDBA281B348A00748062CDC4AC41DFD.png

  var lengthOfLongestSubstring = function(s) {
  let arr = new Array();
  let max = 0;
  for(let i=0; i < s.length; i++) {
    let index = arr.indexOf(s[i])
    if(index !== -1) {
      arr.splice(0,index + 1)
    }
    arr.push(s[i])
    max = Math.max(arr.length,max)
  }
  return max
}

时间复杂度: O(n)

做法描述

  1. 设置一个 arr 滑动窗口,用来接收外部传入的字符串,传入时用indexof()方法进行检索,如果不存在重复元素,就将其装入
  2. 传入时,如果传入值为重复元素,就使用 splice() 方法将重复字符和它之前的字符切割掉,再传入新的字符,并用 max记录此时队列长度
  3. 传入时,如果传入值为非重复元素,就使用 push() 方法直接将字符装入队列,并用max记录此时队列长度

如此,将字符串遍历一遍之后, max 就记录下了最长的无重复字符子串的长度了

最后

这是我的 Leecode 的第一篇打卡,可能语义描述还有不少纰漏,如果有什么问题的话欢迎在评论区指出哦

如果觉得这篇文章的思路对你有帮助,欢迎点个赞哦

BD51B6D89381172236DFA941BB30460F.jpg