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

无重复字符的最长子串

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

总结

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

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

相关推荐
赔罪2 分钟前
C 语言变量说明符
c语言·开发语言·c++·学习·算法·objective-c
@小博的博客15 分钟前
C++初阶学习 第十二弹——stack与queue的介绍和使用
开发语言·数据结构·c++·学习
A Man Of Mould22 分钟前
【数据结构】—— 堆
数据结构·算法
LNTON羚通26 分钟前
视频智能分析软件LiteAIServer摄像机实时接入分析平台噪声监测算法介绍
人工智能·算法·音视频
佑冰26 分钟前
C++ 矩阵旋转
数据结构·c++·算法·c
CYRUS STUDIO30 分钟前
编译 LLVM 源码,使用 Clion 调试 clang
c语言·c++·visual studio·clang·ndk·llvm·clion
qystca35 分钟前
蓝桥杯不知道叫什么题目
数据结构·算法
St_Ludwig37 分钟前
C语言小撰特殊篇-assert断言函数
c语言·c++·后端·算法
益达爱喝芬达40 分钟前
力扣11.23
数据结构·算法·leetcode
飞滕人生TYF41 分钟前
java 排序 详解
java·算法·排序算法·方法