LeetCode 3.Longest Substring Without Repeating Characters 无重复字符的最长子串 Python3 三种解法

7 篇文章 0 订阅
6 篇文章 0 订阅


无重复字符的最长子串 Python3 三种解法)

LeetCode 3.Longest Substring Without Repeating Characters 无重复字符的最长子串 Python3 两种解法

原题在这里
https://leetcode.com/problems/longest-substring-without-repeating-characters/
除了暴力匹配讨论区就是各种滑动窗口的实现,尽量多搬运。

暴力匹配

确实很暴力,复杂度也很高。思路就是枚举所有不重合的情况。因为用了哈希的dict少了一个扫描我的复杂度,运算复杂度比官网稍丢一点点。但是也高达 O ( n 2 ) O(n^2) O(n2),胜在代码简单好懂。按照不重复的规则[abbcab]会拆分出[ab][b][bca][ab]再全部拿来比较。

 def lengthOfLongestSubstring(self, s):
            max_length = 0
            for i in range(len(s)):
                dict = {s[i]:0}
                for j in range(i + 1, len(s)):
                    try:
                        test = dict[s[j]]
                    except Exception as e:
                        dict[s[j]] = j
                    else:
                        break       
                if len(dict) > max_length:
                        max_length = len(dict)
                
            return max_length

https://leetcode-cn.com/problems/two-sum/solution/liang-shu-xiang-jia-by-

滑动窗方法一

先贴官网Java版本。时间窗和暴力匹配的区别举个栗子还是很明白的。再使用的字符串为[abbcab]的栗子,暴力匹配由每个索引位置为一轮,每个索引都要对自己后面的字符再做几次判断,才能依次得到[ab],[b],[cab],[bca],[ab][a],每一轮都会与上一轮比较子串的长度。 但是对于滑动窗方法来说,计算的时候实际使用的是窗口的范围长度i-j,在用于储存窗口的HashSet上执行add和remove,改变窗子的大小,每一轮i或者j前进一格,从滑动路径的历史来看,那些一直位于窗口中的字符的索引就省却了重启重算。暴力匹配每个大循环肯定要有索引位数次,但是这个栗子中左右边界分别只进位了2次和4次。
在这里插入图片描述
为了画图和优化版对比新取一个[abcdbc]的栗子。左边界进位3次,右边界进位刚好是字符串的长度。
在这里插入图片描述

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length();
        Set<Character> set = new HashSet<>();
        int ans = 0, i = 0, j = 0;
        while (i < n && j < n) {
            // try to extend the range [i, j]
            if (!set.contains(s.charAt(j))){
                set.add(s.charAt(j++));
                ans = Math.max(ans, j - i);
            }
            else {
            // clear duplicate value in the set
            // i move one step
                set.remove(s.charAt(i++)); 
            }
        }
        return ans;
    }
}

Python Deque 滑动窗方法

另外官网上找到python deque实现的版本。基本思想类似。特别的点就是利用deque双向特性,对重复的值的位置做判断,然后位移窗。

class Solution:
    # window
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        dequeList = deque()
        uniqueList = []
        globalMax = 0

        for char in s:
            if char in dequeList:
                # char at head
                if dequeList[0] is char:
                    # make sure only one char
                    dequeList.popleft()
                    dequeList.append(char)
                else:
                    # get char at head
                    while dequeList[0] is not char:
                        dequeList.popleft()
                
                    dequeList.popleft()
                    dequeList.append(char)
            else:
                dequeList.append(char)
                globalMax = max(globalMax, len(dequeList))
        
        return globalMax

滑动窗方法二

官网自己给出了上面方法的一个优化,HashSet升级成为HashMap用于存储每个字符对应的位置。HashMap取代HashSet存储每个char对应的位置窗口左边方向进位一步到位。
在这里插入图片描述

  public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length(), ans = 0;
        Map<Character, Integer> map = new HashMap<>(); 
        // current index of character
        // try to extend the range [i, j]
        for (int j = 0, i = 0; j < n; j++) {
        // directly move i to the location of duplication value
            if (map.containsKey(s.charAt(j))) {
                i = Math.max(map.get(s.charAt(j)), i);
            }
            
            ans = Math.max(ans, j - i + 1);
            map.put(s.charAt(j), j + 1); // cover same value 
        }
        return ans;
    }
}
```
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值