剑指 Offer 48. 最长不含重复字符的子字符串

剑指 Offer 48. 最长不含重复字符的子字符串

一、题目

请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。

示例 1:

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

示例 2:

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

示例 3:

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

提示:s.length <= 40000

二、答案

2.1 解题思路

双指针法:

  • 用start作为不重复子串的头指针,用end代表不重复子串的尾指针(用循环是,尾指针可以直接用当前循环的index来表示)
  • 如果遍历的元素重复,则更新hash_table的键值对中对应的index值
  • 每次循环只要元素不重复,都要加入到hash_table中
  • 然后结果长度result = max(result, end-start+1)

2.2 例子示例

以 “dvdlf” 为例,初始化,start指针指向第0个元素,end指针指向1, hash_talbe中已经放了一个元素即{d:0}

  • 初始化start, end, hash_table, result = 0,0, {s[0]:0}, 1

  • 此时默认有一个元素了,所以初始长度result=1

    id01234
    sdvdlf
    指针start = 0,end = 0
    hash_table{d:0}
    result初始:result = 1
  1. 第一次迭代

    • end指针右移一格, 将end所指向的值加入hash_table
    • result = max(result, end-start+1)
    id01234
    sdvdlf
    指针start = 0end = 1
    hash_table{d:0}{d:0,v:1}
    result初始:result = 1result = max(1, 1-0+1)=2
  2. 迭代二次

    • end指针右移一格,,然后发现此时的end指针所指向的值重复

    • 移动start指针到重复元素的后一个元素,注意比较移到重复后一个元素的id与当前的id的大小,取大的那个

      start = max(start, hash_table[s[2]+1) # max(0, 1) = 1
      
    • 更新hash_table中重复键值对的值,那么d:0 变为 d:2

    id01234
    sdvdlf
    指针start = 1end = 2
    hash_table{d:0}{d:0, v:1}{d:2, v:1}
    result12result = max(2, 2-1+1)=2
  3. 迭代第三次

    • end指针右移一格, 将新的键值对加入hash_table
    • result = max(result, end-start+1)
    id01234
    sdvdlf
    指针start = 1end = 3
    hash_table{d:0}{d:0, v:1}{d:2, v:1}{d:2, v:1, l:3}
    result122result = max(2, 3-1+1)=3
  4. 迭代第四次

    • end指针右移一格, 将新的键值对加入hash_table
    • result = max(result, end-start+1)
    id01234
    sdvdlf
    指针start = 1end = 4
    hash_table{d:0}{d:0, v:1}{d:2, v:1}{d:2, v:1, l:3}{d:2, v:1, l:3, f:4}
    result1223result = max(3, 4-1+1) = 4
  5. 循环结束,返回结果result = 4

2.3 代码

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        # 双指针法
        # start, end 分别指向不重复子串的首位序号
        # hash_table用来存访问过的键值对
        # result来表示最长不重复字符串的长度

        # 初始化
        # start, end, hash_table, result = 0, 1, {s[0]:0}, 1
        # 这样的初始化默认字符串大于0,所以要进行空字符串的判断

        if len(s)==0: return 0
        start, hash_table, result = 0, {s[0]:0}, 1
        # 直接将end设置为迭代的index
        for end in range(1, len(s)):
            if s[end] in hash_table:
                start = max(start, hash_table[s[end]]+1)
            hash_table[s[end]] = end
            result = max(result, end-start+1)
        return result
     
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值