您的位置:首页 > 游戏 > 手游 > 成品短视频源码出售_360应用市场_seo是什么岗位的缩写_线上培训机构

成品短视频源码出售_360应用市场_seo是什么岗位的缩写_线上培训机构

2025/1/10 9:45:39 来源:https://blog.csdn.net/xsc2004zyj/article/details/144862608  浏览:    关键词:成品短视频源码出售_360应用市场_seo是什么岗位的缩写_线上培训机构
成品短视频源码出售_360应用市场_seo是什么岗位的缩写_线上培训机构

一.题目描述

3. 无重复字符的最长子串 - 力扣(LeetCode)

二.题目解析

题目还是很好理解的,就是找到一个最长的子串,但是要求子串中没有重复字符且子串必须是连续的。

三.算法原理

1.暴力解法

暴力解法其实就是枚举出所有可能的子串,然后判断子串是否有重复的字符,如果没有则记录下它的长度。遍历完所有子串,返回最长的长度即可。

方法就是固定第一个字符,然后依次增加后面字符的长度即可。

判断一个字符是否重复出现,我们只需要把每一个字符放到一个哈希表中即可,如果一个字符出现的次数>1,说明就重复出现了。

重复出现之后,就要更换第一个字符,然后right指针回到第一个字符,重新开始遍历。

时间复杂度:从整体上看,需要两个指针,left和right,left依次遍历字符串,right在固定好left的前提下也要遍历一边字符串,所以时间复杂度为O(N^2)。 

2.滑动窗口

滑动窗口其实就是在暴力解法的基础上进行优化,最终实现的。下面我们对暴力枚举进行优化:

优化一:当我们在枚举子串时,如果发现最右边的字符已经出现一次了,那么我们right还有必要继续向右走么?

答案:是没有必要~~

因为这已经不符合题目的要求了。题目说的是没有重复字符的最长子串,你已经有了重复字符,你right就算走到结尾,这个子串也不可能是最终结果!

优化二: 既然出现了重复字符,right就没有必要继续往右走了,那么我们就移动left。

我们看下图,当left移动之后,子串中就没有重复字符了,此时我们更新len。

但是还有一个问题,left只移动一位就可以了么?

当然不是了,只是这个例子比较特殊,我们看下面这个例子:

重复字符有可能不是左端点,这时就算你left++,新的子串中依旧有重复字符,这个子串也不可能是答案。

接着,left移动到一个没有重复字符的位置之后,那么right还有必要回到left的位置重新开始遍历子串么?

 没有~~

因为当left移动到这个位置之后,left~right这个区间里已经没有重复字符了,right从left重新走一遍没有任何意义!所以不需要回退right。

所以我们可以得出规律,当出现重复字符后,left应该一直移动直到left~right这个区间内没有重复字符。 当left移动后满足题目要求,我们就更新len。然后此时就继续让right遍历字符串。然后重复这个过程。

总结:在这个过程中,left和right都是向同一个方向移动,没有回退的过程,所以这就可以滑动窗口来解决问题。

时间复杂度:虽然代码是两层循环,但是right只遍历了一边数组,最坏情况下left也会遍历一边数组,所以时间复杂度为2n,整体上就是O(N).

四,代码实现

注意:我们这里既可以使用unordered_map来记录出现次数,也可以开一个大小为128的数组,来模拟哈希表。

int left = 0;
int right = 0;
unordered_map<char,int> dict;
int len = 0;
while (right < s.size())
{//进窗口dict[s[right]]++;//出窗口while (dict[s[right]] > 1){dict[s[left]]--;left++;}len = max(len, right - left + 1);right++;
}
return len;

版权声明:

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

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