LeetCode 3 -无重复字符的最长字串

题目描述
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。

解法一:使用滑动窗口

什么是 sliding window?

其实就是一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列!

如何移动?

我们只要把队列的左边的元素移出就行了,直到满足题目要求!一直维持这样的队列,找出队列出现最长的长度时候,求出解!

时间复杂度为: O ( n ) O(n)

Python实现

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        if not s: return 0
        left = 0
        window = set()
        n =len(s)
        max_len = 0
        cur_len = 0
        for i in range(n):
            cur_len += 1
            while s[i] in window:
                window.remove(s[left])
                left += 1
                cur_len -= 1
            if cur_len > max_len: max_len = cur_len 
            window.add(s[i])
        return max_len

下面是C++实现

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(!s.size()) return 0;
        unordered_set<char> lookup;
        int maxstr = 0;
        int left = 0;
        for(int i=0; i<s.size(); i++)
        {
            while(lookup.find(s[i])!=lookup.end())
            {
                lookup.erase(s[left]);
                left++;
            }
            maxstr = max(maxstr, i-left+1);
            lookup.insert(s[i]);
        }
        return maxstr;
    }
};

关于 unordered_set 的内容参见 C++ unordered_set

解法二:打表,用一个数组来存储出现字符的ASCALL码(C++实现)

其实该方法与解法一无差多少,主要都是利用sliding window,解法二主要是针对C实现,模拟了 lookup.find( )

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        const char *cstr = s.c_str();
        int start = 0, end = 0, maxlen = 0;
        char map[256] = {0};
        map[(int)*(cstr+start)] = 1;
    
        while( *(cstr+end) != 0 )
        {
            maxlen = maxlen>(end-start+1)?maxlen:(end-start+1);
            ++end;
            while(map[ (int)*(cstr+end) ] != 0)
            {
                map[ (int)*(cstr+start) ] = 0;
                ++start;
            }
            map[(int)*(cstr+end)] = 1;
        }
        return maxlen;
    }
};

关于C++ string 转换为 C 字符串的内容详见 C++字符串和C字符串的转换

发布了55 篇原创文章 · 获赞 17 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_38204302/article/details/104345194