week3-leetcode #3-Longest Substring Without Repeating Characters[Medium]
题目链接:https://leetcode.com/problems/longest-substring-without-repeating-characters/
Question
Given a string, find the length of the longest substring without repeating characters.
Example
Given "abcabcbb", the answer is "abc", which the length is 3.
Given "bbbbb", the answer is "b", with the length of 1.
Given "pwwkew", 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.
Solution
time complecity: O(n)
space complecity: O(n)
runtime:22ms
class Solution {
public:
int lengthOfLongestSubstring(string s) {
// 创建一个hashmap用于标记字符的位置
vector<int> hashmap(128, -1);
int max_length = 0;
// 用于标记最大的长度
int str_length = s.length();
// 用于确定开头
int start = 0;
// 用于确定结尾
int end = 1;
for (int i = 0; i < str_length; i++) {
if (hashmap[s[i]] == -1) {
hashmap[s[i]] = i;
} else {
int origin_start = start;
start = max(start+1, hashmap[s[i]]+1);
for (int j = origin_start; j < start; j++) {
if (s[j] != s[i])
hashmap[s[j]] = -1;
}
hashmap[s[i]] = i;
}
max_length = max(max_length, end-start);
end++;
}
return max_length;
}
};
思路:本题有很多种做法,其中一种是找出所有的substring,然后注意比较他们的大小,但其实这样的效率是很低的,需要 O(n3) 的时间复杂度。这里稍微进行了改进,首先理解一个叫做窗口滑动的概念,就是说有一个大小可以变化的窗口从字符串开头开始便利,每次尽可能地使得开口最大,但是必须保证窗口内不能有重复的元素。具体步骤如下:
使用一个vector来标记窗口里面的元素;
给定一个start和end,每次计算end-start的值;
对于start值的确定,每次遇到与集合内相同的元素的时候改变,更改后的值应该是与集合中重复的那个元素的后一个值;
对于end值的确定,每次都会加一来扩大窗口的大小。