03_无重复字符的最长子串

来源:力扣(LeetCode)
链接:题目链接:无重复字符的最长子串
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

问题描述

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

  • 示例 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 由英文字母、数字、符号和空格组成

解题思路

版本一

  1. 定义两个变量:最大长度 maxLen 和 临时长度 tempLen
  2. 遍历字符串
    2.1 用当前字符和之后的字符对比,如果相同,则临时长度就是 两个元素索引的差值
    2.2 对比临时长度和最大长度,如果 临时长度 > 最大长度,把临时长度赋值给最大长度
    2.3 只要发现相同元素,立即退出当前循环
  3. 返回最大长度

注:该版本逻辑来说可行,但不具普适性。在提交代码测试时改进多次扔有问题。代码也会贴出来。有看出改进方法的可以留言给我。一起改进

版本二(滑动窗口)

原文链接:滑动窗口
这道题主要用到思路是:滑动窗口

什么是滑动窗口?

其实就是一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列!

如何移动?

我们只要把队列的左边的元素移出就行了,直到满足题目要求!

一直维持这样的队列,找出队列出现最长的长度时候,求出解!

时间复杂度:O(n)O(n)

代码示例

版本一

func lengthOfLongestSubstring(s string) int {
    maxLen := 0  // 最大长度
    tempLen := 0  // 临时长度
    for idx1, val1 := range s {
        for idx2, val2 := range s[idx1+1:] {
            idx2 = idx1 + 1 + idx2
            if val1 == val2 {
                tempLen = idx2 - idx1
                if tempLen > maxLen {
                    maxLen = tempLen
                }
                break
            }
        }
    }

    if maxLen == 0 {
        maxLen = len(s)
    }
    return maxLen
}

版本二

func in(b int32, s []int32) bool {
    for _, v := range s {
        if b == v {
            return true
        }
    }
    return false
}


func lengthOfLongestSubstring(s string) int {
    maxLen := 0  // 最大长度
    tempLen := 0  // 临时长度
    l := make([]int32, 0) // 滑动队列
    for _, val := range s {
        if !in(val, l) {
            l = append(l, val)
            tempLen = len(l)
            if tempLen > maxLen {
                maxLen = tempLen
            }
        } else {
            // 把相等值之前的删除
            for {
                if  l[0] != val {
                    l = l[1:]
                } else {
                    break
                }
            }
            l = l[1:]  // 把相等值删除
            l = append(l, val)  // 在末尾追加新元素
            tempLen = len(l)
            if tempLen > maxLen {
                maxLen = tempLen
            }
        }
    }
    return maxLen
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值