首页 > 编程语言 >【算法】——滑动窗口专题

【算法】——滑动窗口专题

时间:2024-11-05 21:46:16浏览次数:4  
标签:count 专题 int ret ++ 算法 right 滑动 left

 8e19eee2be5648b78d93fbff2488137b.png

阿华代码,不是逆风,就是我疯

你们的点赞收藏是我前进最大的动力!!

希望本文内容能够帮助到你!!

目录

一:长度最小的子数组

二:无重复字符的最长子串

三:最大连续1的个数

四:将x减到0的最小操作数

五:水果成篮

六:找到字符串中所有字母的异位词

七:串联所有单词的子串

八:最小覆盖子串


一:长度最小的子数组

 

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int left = 0 , right = 0 , sum = 0 , n = nums.length;
        int len = Integer.MAX_VALUE;
        
        for(;right < n ; right++){
            //进入窗口
            sum += nums[right];
            while(sum >= target){
                //更新值
                len = Math.min(len,right - left + 1);
                //出窗口
                sum -= nums[left];
                left++;
            }
        }
        return len == Integer.MAX_VALUE ? 0 : len; 
        
        


    }
}

二:无重复字符的最长子串

3. 无重复字符的最长子串 - 力扣(LeetCode)

class Solution {
    public int lengthOfLongestSubstring(String ss) {
        int left = 0 , right = 0 , ret = 0;
        char[] s = ss.toCharArray();
        int n = s.length;
        int[] hash = new int[128];
        while(right < n){
            hash[s[right]]++;
            while(hash[s[right]] > 1){
                hash[s[left++]]--;//出窗口
            }
            ret = Math.max(ret , right - left + 1);
            right++;
        }
        return ret;

    }
}

三:最大连续1的个数

class Solution {
    public int longestOnes(int[] nums, int k) {
        int left = 0 , right = 0 , count = 0;
        int n = nums.length , ret = 0;
        while(right < n){
            if(nums[right] == 1){
                right++;
            }else{
                count++;
                right++;
            }
            while(count > k){
                if(nums[left] == 1){
                    left++;
                }else{
                    count--;
                    left++;
                }
                
            }
            

            ret = Math.max(ret,right-left);

        } 
        return ret;

    }
}

四:将x减到0的最小操作数

1658. 将 x 减到 0 的最小操作数 - 力扣(LeetCode)

class Solution4 {
    public int minOperations(int[] nums, int x) {
        int left = 0 , right = 0 , count = 0 ,sum = 0;
        int n = nums.length;
        for(int i = 0 ; i < n ; i++){
            sum += nums[i];
        }
        int target = sum - x , tem = 0;
        if(target < 0){
            return -1;
        }
        if(target == 0){
            return n;
        }
        for(; right < n ; right++){
            //进窗口不判断
            tem += nums[right];
            while(tem > target ){
                tem -= nums[left];
                left++;
            }//执行顺序也有讲究,最后一步判断
            if(tem == target){
                count = Math.max(count , right-left+1);
            }
        }
        if(count == 0){
            return -1;
        }
        return n-count;
    }
}

五:水果成篮

904. 水果成篮 - 力扣(LeetCode)

class Solution {
    public int totalFruit(int[] f) {
        Map<Integer,Integer> hash = new HashMap<Integer,Integer>();
        int ret = 0;
        for(int left = 0 , right = 0 ; right < f.length ; right++){
            //进窗口
            int in = f[right];
            hash.put(in,hash.getOrDefault(in,0)+1);
            while(hash.size() > 2){//判断
                //出窗口
                int out = f[left];
                hash.put(out,hash.get(out)-1);
                if(hash.get(out) == 0){
                    hash.remove(out);
                }
                left++;
            }
            ret = Math.max(ret,right - left + 1);
        }
        return ret;
    }
}

六:找到字符串中所有字母的异位词

438. 找到字符串中所有字母异位词 - 力扣(LeetCode)

 

class Solution {
    public List<Integer> findAnagrams(String ss, String pp) {
        List<Integer> list = new ArrayList<Integer>();
        char[] s = ss.toCharArray();
        char[] p = pp.toCharArray();

        int[] hashS = new int[26];
        int[] hashP = new int[26];

        for(char x : p){
            hashP[ x - 'a']++;
        }  

        for(int right = 0 , left = 0 , count = 0 ; right < ss.length() ; right++ ){
            char in = s[right];
            hashS[ in - 'a']++;
            if(hashS[in - 'a'] <= hashP[in - 'a']){
                count++;//进入的是有效字符
            }
            char out = s[left];
            if(right - left + 1 > pp.length()){
                hashS[out - 'a']--;
                if(hashS[out - 'a'] < hashP[out - 'a']){
                    count--;
                }
                left++;
            }
            if(count == pp.length()){
                list.add(left);
            }
        }
        return list;
        
    }
}

七:串联所有单词的子串

30. 串联所有单词的子串 - 力扣(LeetCode)

    class Solution8 {
        public List<Integer> findSubstring(String s, String[] words) {
            List<Integer> ret = new ArrayList<Integer>();
            //先把words中的元素放到HashMap中//每个元素的长度为m,数组长度为n,记录元素种类ele
            Map<String,Integer> hash1 = new HashMap<String,Integer>();
            int m = words[0].length() , n = words.length ,ele = 0;
            for(String ss : words){
                hash1.put(ss,hash1.getOrDefault(ss,0)+1);

            }



            for(int i = 0 ; i < m ; i++ ){
                //wc太绝了hashMap每次i移动时需要初始化一下,要不然上一次的值还存留在HashMap中
                Map<String,Integer> hash2 = new HashMap<String,Integer>();
                for(int left = i , right = i , count = 0 ; right + m <= s.length()  ; right += m){
                    //进窗口
                    String in = s.substring(right,right+m);
                    hash2.put(in,hash2.getOrDefault(in,0)+1);
                    //判断count加不加
                    if(hash2.get(in) <= hash1.getOrDefault(in,0)){
                        count++;
                    }
                    //出窗口
                    while(right - left + 1 > m * n ){
                        String out = s.substring(left,left+m);
                        left+=m;
                        if(hash2.get(out) <= hash1.getOrDefault(out,0)){
                            count--;
                        }
                        hash2.put(out,hash2.get(out)-1);
                    }
                    if(count == n){
                        ret.add(left);
                    }


                }
            }
            return ret;

        }
    }

八:最小覆盖子串

76. 最小覆盖子串 - 力扣(LeetCode)

class Solution {
    public String minWindow(String ss, String tt) {
       //先把要找的字符tt转化为数组并放到哈希表里
       char[] t = tt.toCharArray();
       int[] hash1 = new int[128];
       int kind = 0;//统计tt字符串中有多少种字符
       for(char ch : t){
            hash1[ch]++;
            if(hash1[ch] == 1){
                kind++;
            }
       }

       //同样把字符ss转化为数组
       char[] s = ss.toCharArray();
       int[] hash2 = new int[128];
       int len = Integer.MAX_VALUE;
       int left = 0 , right = 0 , begin = -1 ;
       
       for(int count = 0; right < s.length ; right++){
             //进窗口
            char in = s[right];
            hash2[in]++;
            //判断如果直接判断两个哈希表非常耗费时间引入count
            if(hash1[in] == hash2[in]){
                count++;
            }

            
            //更新结果(如果种类一直相同,那就一直出窗口所以用while)
            while(count == kind){
                if(right - left + 1 < len){
                    begin = left;
                    len = right-left+1;
                }

                //出窗口
                char out = s[left++];
                if(hash2[out] == hash1[out] ){//考虑两种情况,出的是有效字符还是无效字符
                    count--;
                }
                hash2[out]--;  
                
            }
            
       }
            //for循环走完了一直进不去while循环,返回空字符串
            if(len == Integer.MAX_VALUE){
                    return new String();
            }else{
                String ret = ss.substring(begin,begin+len);
                return ret;
            }
       
        
    }
}

标签:count,专题,int,ret,++,算法,right,滑动,left
From: https://blog.csdn.net/2301_80133875/article/details/142793963

相关文章

  • 代码随想录算法训练营第十四天|leetcode226. 翻转二叉树、leetcode101.对称二叉树、le
    1leetcode226.翻转二叉树题目链接:226.翻转二叉树-力扣(LeetCode)文章链接:代码随想录视频链接:听说一位巨佬面Google被拒了,因为没写出翻转二叉树|LeetCode:226.翻转二叉树哔哩哔哩bilibili自己的思路:之前想过就是使用层序遍历的方法来做这一道题目,后来感觉有一些行不通,就......
  • 代码随想录算法训练营第十三天|二叉树的理论基础、二叉树的递归遍历、二叉树的层序遍
    1二叉树的理论基础文章链接:代码随想录视频链接:关于二叉树,你该了解这些!|二叉树理论基础一网打尽,二叉树的种类、二叉树的存储方式、二叉树节点定义、二叉树的遍历顺序哔哩哔哩bilibili1.1二叉树的种类满二叉树所有节点处的值都排满了,没有空的完全二叉树只有在最后......
  • 什么是梯度下降算法
    书接上文,想要用算法解决问题,就不可避免的涉及构造函数L(后面称之为损失函数Loss)求导,和对Loss函数求极小值。而对导函数求极小值就不得不提梯度下降算法,那边本期就来介绍什么是梯度下降算法,以及为什么梯度下降算法能求Loss函数的极小值。什么是梯度?梯度是偏导数组成的向量,,w是......
  • 蓝桥杯排序算法之low B三人组——冒泡,插入,选择
    目录一、题目二、分析三、代码一、题目分别用冒泡,插入,选择对列表li=[3,2,4,5,1,8,6,9,7]进行排序二、分析冒泡排序:它重复地走访要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经......
  • 算法与数据结构——基数排序
    基数排序基数排序(radixsort)的核心思想与计数排序一致,也通过统计个数来实现排序。计数排序适用于数据量n较大但数据范围m比较小的情况。假设我们需要对n=106个学号进行排序,而学号是一个8位数字,这意味着数据范围m=108非常大,使用计数排序需要分配大量内存空间,而基数排序可以避免这......
  • 计算机毕业设计Python+大模型新能源汽车销量预测 汽车销量分析可视化 汽车爬虫 深度学
    温馨提示:文末有CSDN平台官方提供的学长联系方式的名片!温馨提示:文末有CSDN平台官方提供的学长联系方式的名片!温馨提示:文末有CSDN平台官方提供的学长联系方式的名片!作者简介:Java领域优质创作者、CSDN博客专家、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO......
  • SATA系列专题之五:Link Power Management解析
     一、故事前传在之前的文章中,我们已经针对SATA的主要结构进行了较为详细的解析,详见前期文章:1,浅析SATAPhysicalLayer物理层OOB信号;2,SATALinkLayer链路层解析2.0-2.3;3,SATATransportLayer传输层解析3.0-3.4;4,SATACommandLayer命令层解析4.0-4.1;我们这里主要解......
  • PCIe系列专题之二:2.0 Transaction layer事务层概述
    一、故事前传上回我们对PCIe的一些基础概念作了一个宏观的介绍,了解了PCIe是一种封装分层协议(packet-basedlayeredprotocol),主要包括事务层(Transactionlayer),数据链路层(Datalinklayer)和物理层(Physicallayer)。较为详细解释请见之前的文章:PCIe技术概述;二、事务层概述......
  • PCIe系列专题之二:2.1 TLP的前世今生
    一、故事前传之前我们讲了对PCIe的一些基础概念作了一个宏观的介绍,了解了PCIe是一种封装分层协议(packet-basedlayeredprotocol),主要包括事务层(Transactionlayer),数据链路层(Datalinklayer)和物理层(Physicallayer)。较为详细解释请见之前的文章:1.PCIe技术概述;2.0PCIe......
  • PCIe系列专题之二:2.2 TLP事务处理方式解析
    一、故事前传之前我们讲了对PCIe的一些基础概念作了一个宏观的介绍,了解了PCIe是一种封装分层协议(packet-basedlayeredprotocol),主要包括事务层(Transactionlayer),数据链路层(Datalinklayer)和物理层(Physicallayer)。较为详细解释请见之前的文章:1.PCIe技术概述;2.0PCIe......