3. Longest Substring Without Repeating Characters最长不包含重复字符的子字符串Python

给定一个字符串,找到最长子字符串的长度而不重复字符。

Input: 'pwwkew'

Output: 3(wke)

Method 1 找到所有substring中长度最大的

1. 建立一个变量用来存储最大字符串长度(maxlen=0)

2. 两个for循环, 一个设定为子字符串的开头(i)另一个为了遍历它后面所有的字符(j),如果j与前面的字符重复就停止第二层循环。

3. 每次遍历完j之后, 都要比较一下当前的字符串长度与之前运算过的字符串长度的最大值

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        l=len(s)
        maxlen=0
        for i in range(l):
            dummy=[s[i]]
            for j in range(i+1,l):
                if s[j] not in dummy:
                    dummy.append(s[j])
                else:
                    break
            maxlen=max(maxlen,len(dummy))
        return maxlen
'''
maxlen  dummy
2 ['p', 'w']
2 ['w']
3 ['w', 'k', 'e']
3 ['k', 'e', 'w']
3 ['e', 'w']
3 ['w']
3
'''

时间复杂度O(n³)因为每次都要检查子字符串是否有唯一的字符所以将有n*(n+1)/2个字符串

Method 2 滑动窗口Sliding Windows

1. 建立一个dic字典存储s中字母(j)和其对应的位置(i), maxlen用来存储最大长度, start用来做滑动窗口开始的指针

{ dic={}; maxlen=0; start=0 }

2. 先判断字母是否存在于字典中。

如果字母j存在字典中,那么start就从s中重复字母的下一个开始。but考虑到会出现s='adda'这种情况,当处理到最后一位时,a在前面出现,start如果start等于之前出现a的位置的后一位时会变成选取dda这种情况。所以start应该选取当前已经处理到的滑动窗口的位置和字母j对应位置的最大值。

如果不存在于字典中,那么把字母和其在s中的对应位置存入字典,更新最大长度即:当前字母位置i-滑动窗口起始位置start+1(因为位置是从0开始的)。由于之前可能存在不重复的子字符串长度比现在的长,所以要取之前maxlen和现在的最大值

{for i,j in enumerate(s): if j in dic: start=max(start, dic[j]+1); dic[j]=i; maxlen=max(maxlen, i-start+1)}

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        dic={}
        maxlen=0
        start=0
        for i,j in enumerate(s):
            if j in dic:
                start=max(start,dic[j]+1)
            dic[j]=i
            maxlen=max(maxlen,i-start+1)
        return maxlen   

时间复杂度O(n)只需要遍历完s中的字符串就可以了。

Java

和Python相似, 设置左右两个指针

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int res=0;
        char[] c = s.toCharArray();
        Map<Character, Integer> map = new HashMap<>();
        for (int i = 0, j = 0; i < c.length; i++) {//j代表左指针
            j = map.containsKey(c[i]) ? Math.max(j, map.get(c[i])) : j;//当map中存在当前遍历的字符时, 左指针更新
            map.put(c[i], i + 1);
            res = Math.max(res, i - j + 1);
        }
        return res;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值