最长子字符串-无重复字符

Given a string, find the length of the longest substring without repeating characters.

Examples:

Given "abcabcbb", the answer is "abc", which the length is 3.

Given "bbbbb", the answer is "b", with the length of 1.

Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring"pwke" is a subsequence and not a substring.


class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        ilen = 0
        iStart = iEnd = 0
        for a in s:
            pos = s[iStart:iEnd].find(a)
            if pos >= 0:
                if ilen < iEnd - iStart:
                    ilen = iEnd - iStart
                iStart += pos + 1
            iEnd += 1
        if ilen < iEnd - iStart:
            ilen = iEnd - iStart
        return  ilen


空字符串开始,遇到重复调整字符串


在 JavaScript 中,计算无重复的最长子字符串长度有多种实现方法,下面为你介绍几种常见的方法。 ### 滑动窗口结合 Map ```javascript const lengthOfLongestSubstring = str => { const map = new Map(); let left = -1; let maxLength = 0; for (let right = 0; right < str.length; right++) { if (map.has(str[right])) { left = Math.max(left, map.get(str[right])); } maxLength = Math.max(maxLength, right - left); map.set(str[right], right); } return maxLength; }; ``` 此方法使用一个 `Map` 来记录字符及其最新的索引位置,通过维护一个滑动窗口,不断更新窗口的左右边界,以确保窗口内的字符无重复,最终计算出最长无重复子串的长度。例如,对于输入字符串 `'abcabcbb'`,该方法会输出 `3`,因为无重复字符最长子串是 `'abc'` [^1]。 ### 滑动窗口结合 Set ```javascript var lengthOfLongestSubstring = function(s) { const set = new Set(); let i = 0, j = 0, maxlength = 0; if (s.length === 0) { return 0; } for (i; i < s.length; i++) { if (!set.has(s[i])) { set.add(s[i]); maxlength = Math.max(maxlength, set.size); } else { while (set.has(s[i])) { set.delete(s[j]); j++; } set.add(s[i]); } } return maxlength; }; ``` 该方法使用一个 `Set` 来存储当前窗口内的字符,同样采用滑动窗口的思想。当遇到重复字符时,通过移动窗口的左边界,不断删除 `Set` 中的字符,直到重复字符被移除,然后更新 `Set` 并计算最大长度。例如,对于输入字符串 `'pwwkew'`,该方法会输出 `3`,因为无重复字符最长子串是 `'wke'` [^2]。 ### 暴力法 ```javascript function lengthOfLongestSubstring(str) { let maxLength = 0; for (let i = 0; i < str.length; i++) { for (let j = i + 1; j <= str.length; j++) { const subStr = str.slice(i, j); if (isUnique(subStr)) { maxLength = Math.max(maxLength, subStr.length); } } } return maxLength; } function isUnique(str) { const set = new Set(); for (let char of str) { if (set.has(char)) { return false; } set.add(char); } return true; } ``` 暴力法的思路是通过两层循环遍历字符串的所有子串,然后使用一个辅助函数 `isUnique` 来判断子串是否包含重复字符。对于每个无重复的子串,更新最大长度。不过,这种方法的时间复杂度较高,为 $O(n^2)$ [^5]。 ### 复杂度分析 - **滑动窗口结合 Map 和 Set**:时间复杂度为 $O(n)$,因为只需要遍历一次字符串,每个字符最多被访问两次。空间复杂度为 $O(k)$,其中 $k$ 是字符集的大小。 - **暴力法**:时间复杂度为 $O(n^3)$,因为需要两层循环遍历所有子串,并且每次判断子串是否重复需要 $O(n)$ 的时间。空间复杂度为 $O(k)$,其中 $k$ 是字符集的大小。 ### 总结 在实际应用中,建议使用滑动窗口结合 `Map` 或 `Set` 的方法,因为它们的时间复杂度较低,性能更好。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值