Given a string, find the length of the longest substring without repeating characters.
Example 1:
Input: "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.
Example 2:
Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.
Example 3:
Input: "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3.
Note that the answer must be a substring, "pwke" is a subsequence and not a substring.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
定义两个指针i,j(i < j),表示当前扫描的字串区间 [i , j], j每次向后移动的过程中维护一个以s[j] 为key的hash table,hash table 中的值代表字符出现的次数。那么每次j++, 字符区间扩大就会出现两种情况:
1、 新加入的s[j],在hash table中出现过:
此时,需要将字符串区间[i, j]缩短到s[j]只有一个,方式就是i++;并更新hash table;
2、新加入的s[j],在hash table中没有出现过
此时就可以直接跟新hash table,将s[j] 添加到hash table中
最后直接返回出现的最大的字符串区间长度就可以了。
通过hash table 查找s[j]所出现的次数时间复杂度为O(1),而整个的循环次数最多为n次,所以整体的时间复杂度为O(n)。
C++:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int i, j;
int ret = 0;
unordered_map<char, int> hash;
for (i = 0, j = 0; j < s.size(); j++) {
hash[s[j]]++;
while(hash[s[j]] > 1) {
hash[s[i]]--;
i++;
}
ret = max(ret, j - i + 1);
}
return ret;
}
};
C:
使用c语言实现的话,使用一个数组来作为一个hash table。不用担心有hash table 的冲突。
// search repeating character by hashmap
int lengthOfLongestSubstring(char * s){
int i, j, index;
int ret = 0;
int hash[256] = {0};// s 对应的ASCII码作为key
for(i = 0, j = 0; j < strlen(s); j++) {
index = s[j];
hash[index]++;
while(hash[index] > 1) {
int temp = s[i];
hash[temp]--;
i++;
}
ret = ret > (j - i + 1) ? ret : (j - i + 1);
}
return ret;
}
Python:
class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
length = len(s)
p1, p2 = 0, 0
current_len = 0
max_len = 0
target_str = {}
while p1 < length and p2 < length:
if s[p2] in target_str:
del target_str[s[p1]]
p1 += 1
current_len -= 1
else:
target_str[s[p2]] = 1
p2 += 1
current_len += 1
if current_len > max_len:
max_len = current_len
return max_len