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

无重复字符的最长子串

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

总结

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

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

相关推荐
Once_day10 分钟前
C++之《程序员自我修养》读书总结(1)
c语言·开发语言·c++·程序员自我修养
Trouvaille ~20 分钟前
【Linux】TCP Socket编程实战(一):API详解与单连接Echo Server
linux·运维·服务器·网络·c++·tcp/ip·socket
偷吃的耗子25 分钟前
【CNN算法理解】:CNN平移不变性详解:数学原理与实例
人工智能·算法·cnn
坚果派·白晓明32 分钟前
在鸿蒙设备上快速验证由lycium工具快速交叉编译的C/C++三方库
c语言·c++·harmonyos·鸿蒙·编程语言·openharmony·三方库
小镇敲码人39 分钟前
深入剖析华为CANN框架下的Ops-CV仓库:从入门到实战指南
c++·python·华为·cann
dazzle1 小时前
机器学习算法原理与实践-入门(三):使用数学方法实现KNN
人工智能·算法·机器学习
那个村的李富贵1 小时前
智能炼金术:CANN加速的新材料AI设计系统
人工智能·算法·aigc·cann
张张努力变强2 小时前
C++ STL string 类:常用接口 + auto + 范围 for全攻略,字符串操作效率拉满
开发语言·数据结构·c++·算法·stl
万岳科技系统开发2 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
小镇敲码人2 小时前
探索CANN框架中TBE仓库:张量加速引擎的优化之道
c++·华为·acl·cann·ops-nn