【刷题计划】无重复字符的最长子串
2023-03-31 10:32:26 时间
由于疫情,从今天开始在家远程办公,虽然远程看似不需要出门,但是还是又很多不便
- 吃饭是个大问题,以前在公司食堂吃,到点去吃,现在要么自己做,要么外卖都是很麻烦
- 工作时间变长,在公司十到点就去赶班车,在家都没有时间概念,同时感觉任务也更多大家都在加班,内卷更严重了
唉,抽出时间刷题太难了
刷了又不会,会了也记不住,记住了新题型还是不会,好要不要刷题呢?
1今日题目
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。示例 2:
输入: s = "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。示例 3:
输入: s = "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。示例 4:
输入: s = "" 输出: 0
思路
这道题难度是中等,我觉得挺难的,如果没接触过,估计很难在较低的算法复杂度下做出来,
主要考察滑动窗口算法
听起来“滑动窗口”很牛逼,其实就是类似双指针,
在两个指针之内的是符合条件的元素
如果遇到不符合条件得元素则两个指针向右移动,剔除最左边元素
比如abc是一个窗口,当再遇到a时,窗口内变成bca
代码实现如下,算法复杂度为O(n2)
public static int lengthOfLongestSubstring2(String s) {
if (s.length() == 0) {
return 0;
}
int result = 0;
int left = 0;
int right = 0;
int length = 0;
char[] data = s.toCharArray();
List<Character> subString = new ArrayList<>();
while (right < data.length) {
int index = subString.indexOf(data[right]);
while (index >= 0) {
result = Math.max(result, right - left);
subString.remove(0);
length = subString.size();
left++;
index = subString.indexOf(data[right]);
}
length++;
subString.add(data[right]);
right++;
}
return Math.max(result, length);
}
优化1
public int lengthOfLongestSubstring3(String s) {
if (s.length() == 0) {
return 0;
}
Set<Character> subString = new HashSet<>();
int result = 0;
int left = 0, right = 0;
while (right < s.length()) {
char c = s.charAt(right);
while (subString.contains(c)) {
subString.remove(s.charAt(left));
left++;
}
subString.add(c);
right++;
result = Math.max(result, subString.size());
}
return result;
}
优化2
上面实现的方案,在判断当前字符是否出现过时每次都是从前面遍历过数据中再次遍历
这种效率肯定不高,所以考虑通过hash表进行优化
public static int lengthOfLongestSubstring(String s) {
int result = 0;
if (s.length() == 0) {
return result;
}
// 用map保存元素的位置,如果下一个字符在map中出现过
// 证明窗口需要左移,窗口左指针为map中重复元素的下一个
Map<Character, Integer> char2index = new HashMap<>();
//start,end左右指针组成滑动窗口
for (int start = 0, end = 0; end < s.length(); end++) {
char element = s.charAt(end);
if (char2index.containsKey(element)) {
//char2index.get()的地方进行+1操作 ,此处是重点
start = Math.max(char2index.get(element) + 1, start);
}
result = Math.max(result, end - start + 1);
char2index.put(element, end);
}
return result;
}
2小结
滑动窗口的相关的题目还是很有规律可循的,明天争取抽个时间,对滑动窗口的题目做个总结与归纳,把相关题目梳理一遍。
相关文章
- 金融服务领域的大数据:即时分析
- 影响大数据、机器学习和人工智能未来发展的8个因素
- 从0开始构建一个属于你自己的PHP框架
- 如何将Hadoop集成到工作流程中?这6个优秀实践必看
- SEO公司使用大数据优化其模型的5种方法
- 关于Web Workers你需要了解的七件事
- 深入理解HTTPS原理、过程与实践
- 增强分析:数据和分析的未来
- PHP协程实现过程详解
- AI专家:大数据知识图谱——实战经验总结
- 关于PHP的错误机制总结
- 利用数据分析量化协同过滤算法的两大常见难题
- 怎么做大数据工作流调度系统?大厂架构师一语点破!
- 2019大数据处理必备的十大工具,从Linux到架构师必修
- OpenCV中的KMeans算法介绍与应用
- 教大家如果搭建一套phpstorm+wamp+xdebug调试PHP的环境
- CentOS下三种PHP拓展安装方法
- Go语言HTTP Server源码分析
- Go语言HTTP Server源码分析
- 2017年4月编程语言排行榜:Hack首次进入前五十