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

无重复字符的最长子串

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

总结

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

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

相关推荐
wan5555cn3 分钟前
多张图片生成视频模型技术深度解析
人工智能·笔记·深度学习·算法·音视频
u60630 分钟前
常用排序算法核心知识点梳理
算法·排序
鹅毛在路上了2 小时前
C++, ffmpeg, libavcodec-RTSP拉流,opencv实时预览
c++·opencv·ffmpeg
John_ToDebug2 小时前
定制 ResourceBundle 的实现与 DuiLib 思想在 Chromium 架构下的应用解析
c++·chrome·ui
蒋星熠3 小时前
Flutter跨平台工程实践与原理透视:从渲染引擎到高质产物
开发语言·python·算法·flutter·设计模式·性能优化·硬件工程
小欣加油3 小时前
leetcode 面试题01.02判定是否互为字符重排
数据结构·c++·算法·leetcode·职场和发展
3Cloudream3 小时前
LeetCode 003. 无重复字符的最长子串 - 滑动窗口与哈希表详解
算法·leetcode·字符串·双指针·滑动窗口·哈希表·中等
王璐WL3 小时前
【c++】c++第一课:命名空间
数据结构·c++·算法
aramae3 小时前
C++ -- 模板
开发语言·c++·笔记·其他
空白到白4 小时前
机器学习-聚类
人工智能·算法·机器学习·聚类