欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > 力扣 无重复字符的最长子串

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

2024/10/25 15:20:09 来源:https://blog.csdn.net/m0_73547627/article/details/142411697  浏览:    关键词:力扣 无重复字符的最长子串

无重复字符的最长子串

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

题目描述

在这里插入图片描述

题目分析

寻找无重复字符子串,首先要求是子串,然后是无重复
子串可以用滑动窗口确定
问题在于如何确定无重复
如果用暴力枚举子串,复杂度近似 O ( n 3 ) O(n^3) O(n3)是不可接受的
所以我们必须降低复杂度,而暴力枚举的问题就在于首指针的每次移动后窗口都要重新开始扩大,而对于每个窗口我们都要遍历每一个元素以确定无重复。

题目解决

首先,我们假设滑动窗口内的子串一定是无重复的,每当我们移动尾指针进行扩大时,只有当被扩充的元素是非重复的才可以扩大,否则移动首指针直到被扩充的元素不在是重复的。
这样确实降低了复杂度,但也引入了新的问题——如何维护这样一个无重复元素的子串窗口
我们采用计数表示的方法,因为我们不考虑子串中的元素是如何分布的,只在意元素的种类和数量,所以我们可以特化相关特征,并用于表示该子串

代码

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,,n2}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)Si1
非重复子串要求子串中任意字母的个数不能大于1

总结

使用滑动窗口结合双指针,滑动窗口的表示采用哈希表存储字母数量信息的方式
在窗口滑动的过程中维护最大不重复子串长度

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com