LeetCode 3 Longest Substring Without Repeating Characters
2018-02-07 11:31
627 查看
Solution
1 Brute Force
注意:子串(substring)指的是字符串中几个连续 的字符组成的字符串。
子序列(subsequence)指的是字符中几个顺序但不一定连续 的字符组成的字符串。
Intuition:先考虑如何检查一个字符串中是否有重复字符。检查字符串的每个子串是否有重复字符,如果没有则记录其长度。
Algorithm: 假设有个函数
boolean allUnique(String substring)用来判断一个字符串是否有重复字符。
那么如何检查每个子串?只要确定了起始的indice和终止的indice就确定了一个子串。
那么如何判断一个字符串是否有重复字符?可以用set,set中不能包含两个相同元素。
Runtime BF算法会超时
时间复杂度:O(n3)O(n3),见题目solution分析
空间复杂度:需要对子串进行存储,需要的空间是O(k)O(k),k就是
Set的尺寸,
Set的尺寸取决于字符串长度n和字符集(chasrset)大小m(字符串中的字符取自多大的字符集,即最多有多少个无重复字符)。所以空间复杂度为O(min(n,m))O(min(n,m))。
2 Sliding Window
Algorithm暴力很直接(我竟然也没思路。。。),但是太慢,所以如何去优化?
用暴力方法时,我们重复的检查一个子串来看是否有重复子串。但是这是没必要的。如果子串SijSij中的第i个字符到第j-1个字符的组成的子串已经确认过没有重复字符,我们只需要确认字符S[j]S[j]是否已经在子串中。
检查一个字符是否已经在子串中,需要扫描子串,时间复杂度为O(n2)O(n2)。如果使用HashSet 作为滑动窗口,复杂度为O(1)O(1)。
A sliding window 是一个经常在 数组/字符串(array/string) 问题中经常使用的抽象概念。一个窗口是由起始索引和结束索引定义的一系列元素(左闭右开)。一个滑动窗口是指窗口的两个边界向特定方向“滑动”。比如将窗口边界 [i,j)[i,j) 向右移动一个元素,边界就变成了[i+1,j+1)[i<
adc0
mo>+1,j+1) (左闭右开)。
回到本题目,使用HashSet来储存当前窗口[i,j)[i,j)的字符。然后将j向右移动,如果新字符没有在HashSet中,则继续右移,直到S[j]S[j] 已经在字符中了。此时,我们就找出了以i为为起始索引的最大无重复子串。对i进行遍历,即可得到结果。
总结:思路是先考虑到暴力时,判断一个子串有无重复元素时,是直接对该子串进行判断,但该子串的子串可能已经是判断过的,所以就会做重复的工作。那么如何避免做重复的工作? 在滑动窗口的概念中,先固定起始索引,令结束索引右移,如果窗口中有了重复字符,则没有必要再右移结束索引。
滑动窗口的思路适用于 数组/字符串 中的连续元素问题。
时间复杂度:
3 Sliding Window Optimized
对第二种方法进行优化,考虑到在第二步中对窗口进行检查时,固定起始索引,右移结束索引直到字符已经在窗口中重复出现,之后要右移起始索引,注意第二种方法中是将起始索引右移了1个元素,但是其实可以右移多个元素,直到出现重复字符。看solution的说明比较详细。
虽然思路是这样,但是看给的代码还是没懂。代码中实现的方式是,用i,j 表示窗口的起始和结束,这个窗口是抽象的,并没有将元素加入map中。同时,j 不断加1,求 j 对应的无重复子串的起始索引 i 。如何求? 当j 右移时,判断元素s[j] 之前是否出现过(在迭代时,将每个元素(key)和对应索引(value)都加入了map中),使用
count()或
find()可以查到。当出现重复元素时,判断是否更新i 为该元素在之前最后出现时的索引(即该元素在map中对应的value),如果i要更新的值大于i (即起点如果不需要后移,则不更新起点),并且更新map中该元素对应的索引,使其保持为最大。此时i 则表示无重复子串的起点。
相关知识点
c++ set
count(const key_type &key );返回值为key 的元素的个数(0或1),set中没有重复元素,返回值为0或1。
感觉这么总结也太慢了,之后只总结知识点,思路还是直接去原地址看吧。
相关文章推荐
- Leetcode Longest Substring Without Repeating Characters解题报告
- 【编程】leetcode_longest substring without repeating characters
- [LeetCode][Java] Longest Substring Without Repeating Characters
- [LeetCode]3 Longest Substring Without Repeating Characters
- [LeetCode] Longest Substring Without Repeating Characters
- Leetcode: longest-substring-without-repeating-characters
- LeetCode: Longest Substring Without Repeating Characters
- leetcode-java.T003_LongestSubstringWithoutRepeatingCharacters 给定一个字符串,找字符中的最大非重复子串
- LeetCode #Longest Substring Without Repeating Characters#
- leetcode python - Longest Substring Without Repeating Characters
- LeetCode: Longest Substring Without Repeating Characters
- LeetCode Longest Substring Without Repeating Characters
- Longest Substring Without Repeating Characters-----LeetCode
- Leetcode Longest Substring Without Repeating Characters
- [LeetCode] Longest Substring Without Repeating Characters
- LeetCode之Longest Substring Without Repeating Characters
- [LeetCode 003] Longest Substring Without Repeating Characters
- LeetCode | Longest Substring Without Repeating Characters
- 【LeetCode】4. Longest Substring Without Repeating Characters 最长无重复子串
- [LeetCode] Longest Substring Without Repeating Characters