算法练习—无重复字符的最长字串

题目描述

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

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

示例2:

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

示例3:

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

解题思路

暴力解决

  1. 从n位置开始向后遍历,n初始值为0,最长字串长度为len
  2. 字符逐个存入哈希表
  3. 当前不重复字符数m++
  4. 当字符在哈希表中已存在时,将m与len比较,若m>len,将m赋值给len
  5. 清空哈希表
  6. 从n+1处开始继续遍历
  7. 遍历循环结束,len即为最长子串长度

时间复杂度为O(n^2)

流程图

KMP

  1. 从n位置开始向后遍历,n初始值为0,当前子串初始位置m为0,当前子串长度len为0,最长字串长度为len_max
  2. 字符逐个存入哈希表,字符为key,字符在字符串中位置为value,len++
  3. 当字符在哈希表中存在且value值非负,将m的值修改为value_old + 1
  4. 修改value值为n
  5. 将字典中str[m]到str[value_old-1]的key对应的值都修改为-1,len–
  6. 将len与len_max比较,若len>len_max,将len赋值给len_max
  7. 继续从n+1处遍历

时间复杂度为O(n)

滑动

解题算法

C++
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        map<int,int> words;
        map<int,int>::iterator iter;
        int len_max = 0;
        int pos_start = 0;
        int len = 0;
        for(int n = 0;n < s.length();n++)
        {
            iter = words.find(s[n]);
            if(iter == words.end() || iter->second == -1)
            {
                words[s[n]] = n;
                len ++;
            }
            else
            {
                int pos_old = iter->second;
                iter->second = n;
                for(int j = pos_start;j<pos_old;j++)
                {
                    iter = words.find(s[j]);
                    iter->second = -1;
                    len --;
                }
                pos_start = pos_old + 1;
            }
            len_max = len > len_max?len:len_max;
        }
        return len_max;
    }
};
Python3
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        n,len_max,pos_start,len_now = 0,0,0,0
        words = {}
        for n in range(len(s)):
            i = words.get(s[n])
            if i is None or i == -1:
                words[s[n]] = n
                len_now += 1
            else:
                words[s[n]] = n
                for j in range(pos_start,i):
                    words[s[j]] = -1
                    len_now -= 1
                pos_start = i + 1
            len_max = max(len_max,len_now)
        return len_max

滑动窗口

  1. 建立一个空的字典,当前子串长度len为0,最长不重复字符数max为0
  2. 遍历字符串,如果当前字符不在字典中或不在当前不重复子串中len +1
  3. 如果存在则len长度减少重复字符在子串位置
  4. 将字典中key为str[n]的值修改为n
  5. 如果len大于max则把len赋值给max
  6. 遍历结束返回max

时间复杂度为O(n)

解题算法

C++
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        map<int,int> words;
        map<int,int>::iterator iter;
        int len_max = 0;
        int len = 0;
        for(int n = 0;n < s.length();n++)
        {
            iter = words.find(s[n]);
            if(iter == words.end() || iter->second < n - len)
            {
                len ++;
            }
            else
            {
                len = n - iter->second;
            }
            words[s[n]] = n;
            len_max = len > len_max?len:len_max;
        }
        return len_max;
    }
};
Python3
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        word = {}
        num = 0
        ret = 0
        for i in range(len(s)):
            pos = word.get(s[i])
            if  pos == None or pos < i - num:
                num += 1
            else:
                num = i - pos
            word[s[i]] = i
            ret = max(ret,num)
        return ret

本题来源

LeetCode官方链接

猜你喜欢

转载自blog.csdn.net/weixin_35857412/article/details/93037009