leetcode hot100_part03_滑动窗口

滑动窗口是有一个基本的模版的,不要自己想当然哦~

滑动窗口算法思想(附经典例题)_滑动窗口的思想-CSDN博客

滑动窗口也叫同向双指针 ;可以先看一下灵山视频:滑动窗口【基础算法精讲 03】_哔哩哔哩_bilibili

3.无重复字符的最长子串

2024/4/17

DP

原来的做法是,遍历给的字符串,如果字符没有出现(哈希表中不包含该字符)就加入到哈希表,对应的value为0,包含该字符,value为1。然后找到最长的连续0。乍一看没问题,对于题目给的用例3就不行。pwwkew。结果是wke,或许定义为第一次被用到好点?也不太行

用dp。定义dpi:以i位置结尾的最长无重复子串的长度,妈呀,想到了最长括号匹配的那个dp,因为要用下标减去dp。

如果 i+1 位置的字符不包含在 i 位置结尾的最长无重复子串中,那么dp i+1 = dp i + 1;

如果 i+1 位置的字符包含在 i 位置的最长无重复子串中,找到和 i+1 重复字符的下标 index,

dp i+1 = i+1 - index;这个是基于dp的定义。

现在还没解决的问题就是如果判断包不包含 i + 1 位置的字符?哈希,基于之前的经验哈希不太适合解决存储重复key,所以我们不把字符作为哈希的key值,调换一下常规的思维,把下标作为key,字符作为value存储。利用containsValue判断,不行,怎么得到index呢?

在dp遍历更新时同时构造hash,key为字符,value为下标,对于重复元素这样value存储的肯定是距离 i 最近的那个下标,由于dp i 是无重复最长子串,如果 i+1 位置的字符在hash中已存在,获取充分字符的下标x,如果 x <= i - dp i ,那么不包含,否则包含。

再定义一个res迭代更新最大dp就行。

java 复制代码
class Solution {
    public int lengthOfLongestSubstring(String s) {
        char arr[] = s.toCharArray();
        HashMap<Character, Integer> map = new HashMap<>();
        int[] dp = new int [arr.length]; 
        int res = 0;
        for(int i = 0; i < arr.length; i++){
            int x = 0;
            if(i == 0) {
                dp[i] = 1;
            } else {
                if(map.containsKey(arr[i])){
                    x = map.get(arr[i]);
                    if( x < i - dp[i-1] ){
                        dp[i] = dp[i-1] + 1;
                    } else {
                        dp[i] = i - x;
                    }
                } else {
                    dp[i] = dp[i-1] + 1;
                }
            }
            map.put(arr[i], i);
            res = Math.max(dp[i], res);   
        }
        return res; 
    }
}

滑动窗口

伪代码,时间复杂度为O(n),Link

滑动窗口算法的时间复杂度通常是 O(n)的,其中 n 表示字符串或数组的长度。这是因为滑动窗口算法只需要对每个元素至多遍历一遍,同时也只需要在窗口的左右边界上移动,因此总的操作次数不会超过 2n 次。

复制代码
int len...
int l =0;
//for循环中定义r
for(int r = 0; r < len; r++){
    //r每到一个位置需要执行的操作
    状态更新(因为r移动)
    
    while(满足条件){
        更新结果;
        状态更新(因为l移动)
        移动左指针,l++;
        
    }
}
return 结果 

左指针移动的时候,不要忘记更新当前的集合状态;

用list集合存储的时候更新左边界,是list.remove(0);

用set集合本身就是去重的,为啥更新左边界的时候一定要去除呢,想清楚

438.找到字符串中所有字母异位词

看这个题解:link

这种字符串异位词啥的,最小覆盖子串这种,关键的还是词频,定义数组记录每个字母出现的次数;再做就有思路了;

第一种定长的,感觉算不上标准的滑动窗口,就是判断词频数组是否一致

第二种,标准的模版,什么时候满足,为什么只保证当前的right就行?因为right经过的地方都满足

相关推荐
AI科技星6 分钟前
基于32维Cayley_Dickson超复数的全域拓扑统一场论——反重力、真空自持供能、维度瞬移与星际宇宙脑秩序体系
人工智能·学习·算法·机器学习·数据挖掘
aichitang202413 分钟前
数论变换(NTT)
c++·算法·fft·ntt
_olone16 分钟前
AtCoder Beginner Contest 465 D - X to Y
c++·算法
青山木19 分钟前
Hot 100 --- LRU 缓存
java·数据结构·算法·leetcode·链表·缓存·哈希
“码”力全开20 分钟前
ONVIF摄像头接入项目实战记录
人工智能·算法·边缘计算
子建莫敌40 分钟前
ROS2 面试总结
面试·职场和发展
AI科技星1 小时前
公理化数学化学|48小时确权终稿(完整投产包)
人工智能·数学·算法·重构·拓扑学·乖乖数学·全域数学
程序员杰哥1 小时前
接口自动化测试项目框架详解
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·接口测试
想你依然心痛1 小时前
AtomCode在算法竞赛中的实战体验:LeetCode周赛辅助编程
linux·算法·leetcode
SilentSamsara1 小时前
模型部署方案选型:REST/gRPC/批量推理/边缘部署的场景决策
人工智能·深度学习·算法·机器学习