力扣 无重复字符的最长子串

无重复字符的最长子串

https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/

题目描述

题目分析

寻找无重复字符子串,首先要求是子串,然后是无重复

子串可以用滑动窗口确定

问题在于如何确定无重复

如果用暴力枚举子串,复杂度近似 O ( n 3 ) O(n^3) O(n3)是不可接受的

所以我们必须降低复杂度,而暴力枚举的问题就在于首指针的每次移动后窗口都要重新开始扩大,而对于每个窗口我们都要遍历每一个元素以确定无重复。

题目解决

首先,我们假设滑动窗口内的子串一定是无重复的,每当我们移动尾指针进行扩大时,只有当被扩充的元素是非重复的才可以扩大,否则移动首指针直到被扩充的元素不在是重复的。

这样确实降低了复杂度,但也引入了新的问题------如何维护这样一个无重复元素的子串窗口

我们采用计数表示的方法,因为我们不考虑子串中的元素是如何分布的,只在意元素的种类和数量,所以我们可以特化相关特征,并用于表示该子串

代码

c 复制代码
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map<char, int> window;
        int ans = 0;
        int j = 0, slen = s.length(), i = 0;
        if(slen == 1) return 1;
        while(j < slen){
            auto it = window.find(s[j]);
            if(it == window.end()){
                window[s[j]] = 1;
                if((j - i + 1 ) > ans){
                    ans = (j - i + 1 );
                }
            } 
            else if(it->second == 1){
                while(window[s[j]] && i < j){
                    --window[s[i]];
                    ++i;
                }
                ++window[s[j]];
            }
            else{
                window[s[j]] = 1;
                if((j - i + 1 ) > ans){
                    ans = (j - i + 1 );
                }
            }
            
            // printf("%d %d %d %d\n",i, j, window[s[j]], window[s[i]]);
            ++j;
        }
        return ans;
    }
};

Abstract

设 s i s_i si 为子串中的元素, f ( s i ) f(s_i) f(si) 为 s i s_i si 所表示的字符

无重复字符串表示如下
S = { ( s i , s i + 1 ) ∣ i = 0 , 1 , ... , n − 2 } s . t . ∀ s i , s j f ( s i ) ≠ f ( s j ) S = \{(s_i,s_{i+1}) \space | \space i = 0, 1, \dots , n-2\} \quad s.t. \space\forall s_i, s_j \quad f(s_i) \ne f(s_j) S={(si,si+1) ∣ i=0,1,...,n−2}s.t. ∀si,sjf(si)=f(sj)

提取特征表示
S ∗ : = cnt ( e a c h e l e m e n t ) ( dim ⁡ ( S ∗ ) = 26 ) S i ∗ ≤ 1 \boldsymbol{S^*} := \text{cnt}(each\space element)\quad(\dim(\boldsymbol{S^*})=26)\\ S^*_i \le1 S∗:=cnt(each element)(dim(S∗)=26)Si∗≤1

非重复子串要求子串中任意字母的个数不能大于1

总结

使用滑动窗口结合双指针,滑动窗口的表示采用哈希表存储字母数量信息的方式

在窗口滑动的过程中维护最大不重复子串长度

相关推荐
Dobby_0516 分钟前
【Go】C++ 转 Go 第(一)天:环境搭建 Windows + VSCode 远程连接 Linux
linux·运维·c++·vscode·golang
咸鱼爱学习1 小时前
【题解】B2613【深基1.习5】打字速度
数据结构·c++·算法
一匹电信狗1 小时前
【C++】C++风格的类型转换
服务器·开发语言·c++·leetcode·小程序·stl·visual studio
syt_biancheng1 小时前
C++ 多态(1)
jvm·c++·学习
学学学无无止境1 小时前
力扣-上升的温度
leetcode
云青黛1 小时前
轮廓系数(一个异型簇的分类标准)
人工智能·算法·机器学习
云青黛2 小时前
肘部法找k
人工智能·算法·机器学习·聚类
std78792 小时前
用C++ 实现屏幕保护程序
开发语言·c++
CHANG_THE_WORLD2 小时前
if条件语句 三目运算符 汇编分析
汇编·算法·条件语句·if 语句·汇编分析·条件语句汇编分析
tumu_C2 小时前
无用知识研究:在trailing return type利用decltype,comma operator在对函数进行sfinae原创 [二]
开发语言·c++·算法