原题链接
题目描述
找到一个字符串中不出现重复字符的最长字符串并返回该子串长度
解题思路
发现碰到这种问题我的第一反应永远是暴力解法×
固然能完成题目,但效率是真的低下qwq
最暴力的就是O(n²),两个for循环嵌套找子串,比较简单,代码就不贴了
其他解法
法一:滑动窗口
——解决字符串问题&数组问题的常用方法
和暴力解法的基本思想是相同的,使用hashset来模拟滑动窗口找到符合条件的子串
时间复杂度O(n)
class Solution {
public int lengthOfLongestSubstring(String s) {
int count = 0, begin = 0, end = 0; //begin和end分别为窗口的开始和结束位置
Set<Character> slide = new HashSet<>();
while (begin < s.length() && end < s.length()) {
char tmp = s.charAt(end);
if (!slide.contains(tmp)) {
slide.add(tmp);
count = Math.max(count, slide.size());
end++;
}
else {
slide.remove(s.charAt(begin));
begin++;
}
}
return count;
}
}
法二:优化的滑动窗口
做一个character和index之间的映射(采用hashmap或数组(利用ASCII))
和法一相比,多了一个index信息,滑动窗口的begin不再需要一位一位增加,可以从已有的重复字符的下一个字符开始
class Solution {
public int lengthOfLongestSubstring(String s) {
int res = 0, begin = 0;
Map<Character, Integer> map = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
if (map.containsKey(s.charAt(i))) {
begin = Math.max(begin, map.get(s.charAt(i)));
}
res = Math.max(i - begin + 1, res);
map.put(s.charAt(i), i + 1);
}
return res;
}
}
数组方法同理。
数组和hashmap的区别在于,当数据集的规模与内容,这题中均为字符,可以利用ASCII码来构造数组