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-Advancegithub.com总结
以上是生活随笔为你收集整理的cstring判断是否包含子串_最长子串-滑动窗口的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: Win10怎么给本地账户添加管理员权限
- 下一篇: k8s ready 不调度_从零开始学K