leetcode3/剑指offer48.无重复字符的最长子串

127 篇文章 3 订阅
50 篇文章 1 订阅

1.题目描述

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

示例 1:

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

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

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

2.解题思路

解法一:

先不考虑代码怎么实现,如果给一个例子中的例子 "abcabcbb",让你手动找无重复字符的子串,该怎么找。博主会一个字符一个字符的遍历,比如 a,b,c,然后又出现了一个a,那么此时就应该去掉第一次出现的a,然后继续往后,又出现了一个b,则应该去掉一次出现的b,以此类推,最终发现最长的长度为3。所以说,需要记录之前出现过的字符出现的位置,所以可以使用 HashMap 来建立字符和其最后一次出现位置之间的映射。

窗口的右边界 i 就是当前遍历到的字符的位置,为了求出窗口的大小,需要一个变量 left 来指向滑动窗口的左边界,这样,如果当前遍历到的字符从未出现过,那么直接扩大右边界,如果之前出现过,那么就分两种情况,在或不在滑动窗口内,如果不在滑动窗口内,那么就没事,当前字符可以加进来,如果在的话,就需要先在滑动窗口内去掉这个已经出现过的字符了,去掉的方法并不需要将左边界 left 一位一位向右遍历查找,由于 HashMap 已经保存了该重复字符最后出现的位置,所以直接移动 left 指针就可以了。维护一个结果 res,每次用出现过的窗口大小来更新结果 res,就可以得到最终结果。

left 指向滑动窗口内无重复子串左边的起始位置的前一个,由于是前一个,所以初始化就是 -1,然后计算窗口长度的时候,直接用 i-left 即可,用来更新结果 res。

参考链接:https://www.cnblogs.com/grandyang/p/4480780.html


解法二:

另一种实现类似 leetcode438.找到字符串中所有字母异位词,当出现重复字符时,移动left

3.代码实现

解法一:

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        left=-1
        res=0
        hash={}
        for i in range(len(s)):
            if s[i] in hash and hash[s[i]]>left:
                left=hash[s[i]]
                hash[s[i]]=i
            else:
                hash[s[i]]=i
            res=max(res,i-left)
        return res

解法二:

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        if not s:
            return 0
        window = {}
        left = 0
        right = 0
        res = 0
        while right < len(s):
            window[s[right]] = window.get(s[right],0)+1
            right += 1
            # 判断的是right-1,因为right已经加1了
            while window[s[right-1]] > 1:
                window[s[left]] -= 1
                left += 1
            res = max(res, right - left)
        return res

解法三:

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        from collections import Counter
        if not s:
            return 0
        window = {}
        left = 0
        right = 0
        res = 0
        while right < len(s):
            if window.get(s[right],0) == 0:
                window[s[right]] = window.get(s[right],0)+1
                res = max(res, right - left + 1)
                right += 1
            else:
                while window[s[right]] > 0:
                    window[s[left]] -= 1
                    left += 1
        return res

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值