一、问题描述
Given a string, find the length of the longest substring without repeating characters.
Examples:
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.
二、我的解法
时间O(n^2)的解法,i有n个开始点,j有n个可能的结束点。每次只判断s[j]是否在当前的substring里。 (是n2还是n3?)
用hashSet帮助判断当前要加入的char是否已经存在在substring里。
class Solution {
public int lengthOfLongestSubstring(String s) {
char[] char_arr = s.toCharArray();
int max_len = 0;
int cur_len;
Set<Character> appeared = new HashSet<Character>();
for(int i = 0; i < char_arr.length; i ++){
int j = i;
appeared.clear();
cur_len = 0;
while(j < char_arr.length && appeared.add(char_arr[j])){
cur_len ++;
j ++;
}
if(cur_len > max_len){
max_len = cur_len;
}
}
return max_len;
}
}三、淫奇技巧
https://leetcode.com/articles/longest-substring-without-repeating-characters/
1. O(2n)解法
滑动窗口。从左往右扫描,当遇到重复字母时,以上一个重复字母的index +1,作为新的搜索起始位置。因为设s[j]是substring[i, j)的重复元素。如果再从包含s[j]的字串i+1重新搜索已经没有必要了,因为该字串结果必定小于[i, j)。所以直接从重复字母的index +1,作为新的搜索起始位置。
当要加入的s[j]重复了,就从hashset里依次删除元素,直到把重复的那个元素删除为止,再把s[j]加入。
-
Time complexity : O(2n)=O(n). 最坏情况是每个元素被i和j各遍历一遍。
-
Space complexity : O(min(m,n)). 和我的解法一样。m是input string里不同char的数量,n是string长度。
public class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
Set<Character> set = new HashSet<>();
int ans = 0, i = 0, j = 0;
while (i < n && j < n) {
// try to extend the range [i, j]
if (!set.contains(s.charAt(j))){
set.add(s.charAt(j++));
ans = Math.max(ans, j - i);
}
else {
set.remove(s.charAt(i++));
}
}
return ans;
}
}2. O(n解法)
思路和上面解法一样,但是怎样从index+1开始搜索更胜一筹。存储用了hashmap,有char到index的映射信息。
public class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length(), ans = 0;
Map<Character, Integer> map = new HashMap<>(); // current index of character
// try to extend the range [i, j]
for (int j = 0, i = 0; j < n; j++) {
if (map.containsKey(s.charAt(j))) {
i = Math.max(map.get(s.charAt(j)), i);
}
ans = Math.max(ans, j - i + 1);
map.put(s.charAt(j), j + 1);
}
return ans;
}
}四、反思&收获
1. hashset是好东西
2. 多存有用的信息可以减少复杂度;
3. 算复杂度要继续加强
4. 搜索字符串策略的优化要加强~
本文探讨了如何寻找字符串中最长的无重复字符子串,提供了两种高效算法:一种使用滑动窗口配合HashSet达到O(2n)的时间复杂度,另一种通过HashMap优化搜索起点实现O(n)的时间复杂度。
375

被折叠的 条评论
为什么被折叠?



