欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

cstring判断是否包含子串_最长子串-滑动窗口

发布时间:2023/12/15 编程问答 35 豆豆
生活随笔 收集整理的这篇文章主要介绍了 cstring判断是否包含子串_最长子串-滑动窗口 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

接下来我会找出LeetCode中一些比较有代表性的题,带来它的算法和讲解

很多题目,使用一般的暴力算法很多都能解出来,但时间复杂度可能是 O(n3),会比最优解慢很多,尤其是数据量变大时。

在我们实际项目中编写代码时会遇到各种情况,组织数据,处理数据,如果能在特定的情况使用特定的算法,就可以发挥事半功倍的效果,很有现实意义。

原题链接

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 :
输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

暴力

这是一个比较经典的问题,查找无重复最长子串。

先看我最开始给出的解法

思路比较简单,借助Set,我可以很快的判断一个字符是否在一个集合里

从第一个字符开始开始遍历每个字符,然后从这个字符开始到最后一个字符,依次加入Set

如果Set没有就加入,一旦出现重复判断之前的最长长度和当前的最长长度,取较大值,Set清空

class Solution {public int lengthOfLongestSubstring(String s) {Set<Integer> t = new HashSet<>();int max = 0;for (int i = 0; i < s.length(); i++) {for (int j = i; j < s.length(); j++) {int a = s.charAt(j);if (!t.contains(a)) {t.add(a);} else {max = t.size() > max ? t.size() : max;t.clear();break;}}}if(t.size() > max){max = t.size();}return max;} }

滑动窗口

先看解法

class Solution {public int lengthOfLongestSubstring(String s) {int max = 0;Set<Character> t = new HashSet<>();for (int i = 0, j = 0; i < s.length(); ) {if (j >= s.length()) {break;}if (!t.contains(s.charAt(j))) {t.add(s.charAt(j));max = Math.max(max, j - i +1);j++;}else{t.remove(s.charAt(i++));}}return max;} }

暴力法有个明显的问题,比如我判断 abcabcbb

在第一字符时判断

a ab abc abca

在第二个字符时判断

b bc bca

会有大量重复且不必要的判断

那么怎么避免呢

当我判断第一个字符到 abca 时,不在完全退回第二个字符重新判断,而是保留右侧的配置,左侧右移一位,那么现在就成了不重复时右侧游标右移,存在重复字符时,左侧游标右移,同时记录中间的最长长度

左侧游标和右侧游标依次滑动右移,就仿佛是一个会移动的窗口,中间的某个最大长度即为不含有重复字符的最长子串

滑动窗口优化

当我们遇到一个字符串pasdsad,使用上述算法

p pa pas pasd asd sd d ds

因为下一个字符是s,所以左侧游标移动了3次才移除了当前窗口内s

但是如果直接能跳到s位置呢

那么又会减少很多次操作

class Solution {public int lengthOfLongestSubstring(String s) {int n = s.length(), ans = 0;Map<Character, Integer> map = new HashMap<>();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;} }

通过Map映射记录上一个重复字符的位置,发生重复是可使左侧游标直接跳到之前的重复位置。

关注我的Github项目,开启Java进阶之路,欢迎star

Asens/Java-Advance​github.com

总结

以上是生活随笔为你收集整理的cstring判断是否包含子串_最长子串-滑动窗口的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。