OJ刷题日记:4、滑动窗口(2)

简介: OJ刷题日记:4、滑动窗口(2)

1、904.水果成篮

题目:

你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。


你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:


你只有 两个 篮子,并且每个篮子只能装 单一类型 的水果。每个篮子能够装的水果总量没有限制。

你可以选择任意一棵树开始采摘,你必须从 每棵 树(包括开始采摘的树)上 恰好摘一个水果 。采摘的水果应当符合篮子中的水果类型。每采摘一次,你将会向右移动到下一棵树,并继续采摘。

一旦你走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘。

给你一个整数数组 fruits ,返回你可以收集的水果的 最大 数目。


示例 1:


输入:fruits = [1,2,1]

输出:3

解释:可以采摘全部 3 棵树。

示例 2:


输入:fruits = [0,1,2,2]

输出:3

解释:可以采摘 [1,2,2] 这三棵树。

如果从第一棵树开始采摘,则只能采摘 [0,1] 这两棵树。

示例 3:


输入:fruits = [1,2,3,2,2]

输出:4

解释:可以采摘 [2,3,2,2] 这四棵树。

如果从第一棵树开始采摘,则只能采摘 [1,2] 这两棵树。

示例 4:


输入:fruits = [3,3,3,1,2,1,1,2,3,3,4]

输出:5

解释:可以采摘 [1,2,1,1,2] 这五棵树。

提示:


1 <= fruits.length <= 105

0 <= fruits[i] < fruits.length

这里的算法原理还是滑动窗口,这里刚好我学过了map在c++的专栏里面有,所以这里直接说我的写法思路,这里是利用滑动窗口,还是那四步


1、left=0、rigjt=0


2、进窗口,就是右边指针进行++,然后进行存入map里面,也就是map的键值就是fruits的的数据,然后后面计数++


3、出窗口,就是当map的size大于2的时候就进行出窗口,这里注意需要利用迭代器进行获取需要出窗口值的地址,然后当second的值为0时需要把这个删除了


4、更新结果,这里就是在记录一下最大两个范围就可以了,然后进行返回。

class Solution {
public:
    int totalFruit(vector<int>& fruits) {
        int left=0,right=0,ret=0,n=fruits.size();
        map<int,int> m;
        while(right<n)
        {
            ++m[fruits[right]];
            while(m.size()>2)
            {        
                auto it = m.find(fruits[left]);
                --it->second;
                if(it->second==0)
                    m.erase(it);
 
                ++left;
            }
            ret=max(ret,right-left+1);
            ++right;
        }
        return ret;
    }
};

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

题目:

给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。


异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。


示例 1:


输入: s = "cbaebabacd", p = "abc"

输出: [0,6]

解释:

起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。

起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。

示例 2:


输入: s = "abab", p = "ab"

输出: [0,1,2]

解释:

起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。

起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。

起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。

提示:


1 <= s.length, p.length <= 3 * 104

s 和 p 仅包含小写字母

先看题目这里是需要找到异位词,也就是abc、acb、bac、bcd等等,不一定需要完全相当,这里就可以利用哈希表了,这里只有小写字母,所以这里就直接创建了一个数组用来存入p和s的然后进行匹配,这里是创建了一个count进行维护数组,也就是碰到有效的字符count进行++,然后当做左边减去右边+1大于p的大小就是出窗口的时候,这里就是创建了一个vector用来记录坐标的起始坐标,出窗口的时候就是看有没有有效数字,有有效数字的时候count--,如下方代码所示

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        int hashi1[26]={0};//记录p的字母个数
        for(auto e:p)
            hashi1[e-'a']++;
        int count=0;//用来判断维护字母有效个数
        int hashi2[26]={0};//统计s可能出现的子串个数
        int m=p.size();
        vector<int> ret;
        for(int left=0,right=0;right<s.size();++right)
        {
            char in=s[right];
            if(++hashi2[in-'a']<=hashi1[in-'a'])
                count++;
            if(right-left+1>m)
            {
                char out=s[left++];
                if(hashi2[out-'a']--<=hashi1[out-'a'])
                    count--;
            }
            if(count==m)
                ret.push_back(left);
        }   
        return ret;
    }
};

3、30.串联所有单词的子串

题目:

给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。


s 中的 串联子串 是指一个包含  words 中所有字符串以任意顺序排列连接起来的子串。


例如,如果 words = ["ab","cd","ef"], 那么 "abcdef", "abefcd","cdabef", "cdefab","efabcd", 和 "efcdab" 都是串联子串。 "acdbef" 不是串联子串,因为他不是任何 words 排列的连接。

返回所有串联子串在 s 中的开始索引。你可以以 任意顺序 返回答案。


示例 1:

输入:s = "barfoothefoobarman", words = ["foo","bar"]

输出:

[0,9]


解释:因为 words.length == 2 同时 words[i].length == 3,连接的子字符串的长度必须为 6。

子串 "barfoo" 开始位置是 0。它是 words 中以 ["bar","foo"] 顺序排列的连接。

子串 "foobar" 开始位置是 9。它是 words 中以 ["foo","bar"] 顺序排列的连接。

输出顺序无关紧要。返回 [9,0] 也是可以的。


示例 2:

输入:s = "wordgoodgoodgoodbestword", words = ["word","good","best","word"]

输出:[]

解释:因为 words.length == 4 并且 words[i].length == 4,所以串联子串的长度必须为 16。

s 中没有子串长度为 16 并且等于 words 的任何顺序排列的连接。

所以我们返回一个空数组。


示例 3:

输入:s = "barfoofoobarthefoobarman", words = ["bar","foo","the"]

输出:[6,9,12]

解释:因为 words.length == 3 并且 words[i].length == 3,所以串联子串的长度必须为 9。

子串 "foobarthe" 开始位置是 6。它是 words 中以 ["foo","bar","the"] 顺序排列的连接。

子串 "barthefoo" 开始位置是 9。它是 words 中以 ["bar","the","foo"] 顺序排列的连接。

子串 "thefoobar" 开始位置是 12。它是 words 中以 ["the","foo","bar"] 顺序排列的连接。


提示:


1 <= s.length <= 104

1 <= words.length <= 5000

1 <= words[i].length <= 30

words[i] 和 s 由小写英文字母组成

先看题目,这里和上题原理差不多,也是利用滑动窗口和哈希进行解答,这里是利用map记录words里面的字符串,然后这次在进窗口的时候不是一个一个移动了,这次是words里面一个字符串的长度,也就是单词多长移动多长,如示例一就是一次移动三个,所以这里需要注意一下,然后出窗口的时候就是和上面一题差不多,这里就是把map的数值进行--,然后也是用count进行维护,更新结果的时候是当words总长度等于count的时候就进行更新,如下方代码所示

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        int len=words[0].size(),m=words.size();
        map<string,int> hash1;
        for(auto& e:words)
            hash1[e]++;
        vector<int> v;
        int count=0;
        for(int i=0;i<len;i++)
        {
            map<string,int> hash2;
            for(int left=i,right=i,count=0;right+len<=s.size();right+=len)
            {
                string in=s.substr(right,len);
                hash2[in]++;
                if(hash1.count(in)&&hash2[in]<=hash1[in]) 
                    count++;
                if(right-left+1>len*m)
                {
                    string out=s.substr(left,len);
                    if(hash1.count(out)&&hash2[out]<=hash1[out])
                        count--;
                    hash2[out]--;
                    left+=len;
                }
                if(count==m) 
                    v.push_back(left);
            }
        }
        return v;
    }
};

4、76.最小覆盖子串

题目:

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 ""


注意:

  • 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
  • 如果 s 中存在这样的子串,我们保证它是唯一的答案。

示例 1:

输入:s = "ADOBECODEBANC", t = "ABC"

输出:"BANC"

解释:最小覆盖子串 "BANC" 包含来自字符串 t 的 'A'、'B' 和 'C'。


示例 2:

输入:s = "a", t = "a"

输出:"a"

解释:整个字符串 s 是最小覆盖子串。


示例 3:

输入: s = "a", t = "aa"

输出: ""

解释: t 中两个字符 'a' 均应包含在 s 的子串中,

因此没有符合条件的子字符串,返回空字符串。


提示:

  • m == s.length
  • n == t.length
  • 1 <= m, n <= 105
  • st 由英文字母组成


先看题目,这题是覆盖,如示例一,只要有一个A一个B一个C的时候,这个就是子串,也就是说中间可以重复,算法思路也就是滑动窗口,这个使用一个128长度的数组进行记录t的字符,也就是记录每个字符出现几次,然后用一个128长度的数组进行维护s的字符,count也是用来维护,和前两题差不多,这里的出窗口条件就是当有效字符等于count的时候进开始进行更新最小的子串长度以及起始地址,然后进行出窗口,在返回就可以了

class Solution {
public:
    string minWindow(string s, string t) {
        int hash1[128]={0};
        int kinds=0;
        for(auto e:t)
            if(hash1[e]++==0)
                kinds++;
        int hash2[128]={0};
        int minlen=INT_MAX,begin=-1;
        for(int left=0,right=0,count=0;right<s.size();right++)
        {
            char in=s[right];
            if(++hash2[in]==hash1[in])
                count++;
            while(count==kinds)
            {
                if(right-left+1<minlen)
                {
                    minlen=right-left+1;
                    begin=left;
                }
                char out=s[left++];
                if(hash2[out]--==hash1[out])
                    count--;
            }
        }
        if(begin==-1) return "";
        else return s.substr(begin,minlen);
    }
};





目录
相关文章
|
存储 运维 持续交付
Nacos架构与原理 - 寻址机制
Nacos架构与原理 - 寻址机制
232 0
|
11月前
|
数据采集 JSON Java
利用Java获取京东SKU接口指南
本文介绍如何使用Java通过京东API获取商品SKU信息。首先,需注册京东开放平台账号并创建应用以获取AppKey和AppSecret。接着,查阅API文档了解调用方法。明确商品ID后,构建请求参数并通过HTTP客户端发送请求。最后,解析返回的JSON数据提取SKU信息。注意遵守API调用频率限制及数据保护法规。此方法适用于电商平台及其他数据获取场景。
|
存储 运维 Prometheus
都有什么报警监控工具
都有什么报警监控工具
274 1
|
机器学习/深度学习 算法 数据安全/隐私保护
基于贝叶斯优化卷积神经网络(Bayes-CNN)的多因子数据分类识别算法matlab仿真
本项目展示了贝叶斯优化在CNN中的应用,包括优化过程、训练与识别效果对比,以及标准CNN的识别结果。使用Matlab2022a开发,提供完整代码及视频教程。贝叶斯优化通过构建代理模型指导超参数优化,显著提升模型性能,适用于复杂数据分类任务。
|
NoSQL 算法 Redis
Redis集群哈希槽数据分片
Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽. 集群的每个节点负责一部分hash槽。这种结构很容易添加或者删除节点,并且无论是添加删除或者修改某一个节点,都不会造成集群不可用的状态。
500 0
Redis集群哈希槽数据分片
|
机器学习/深度学习 运维 监控
信息安全:入侵检测技术原理与应用.(IDS)
信息安全:入侵检测技术原理与应用.(IDS)
929 1
|
前端开发 JavaScript API
Vue.Draggable 和 React Beautiful DND 有什么区别
Vue.Draggable 和 React Beautiful DND 是两个用于 Vue.js 和 React 的拖拽排序库。Vue.Draggable 提供 Vue 指令,适合 Vue 应用,支持列表排序和自定义数据处理,具有多种事件回调和配置选项。React Beautiful DND 则为 React 提供组件,能处理复杂拖拽场景,通过回调函数更新状态,配置选项包括限制拖拽范围和自定义动画。
|
前端开发 JavaScript UED
浅谈JS——理解回调函数
浅谈JS——理解回调函数
313 0
|
容器 Kubernetes 网络协议
在Istio上创建自定义的ingress-gateway
我们都知道,在istio中可以通过ingress gateway将服务暴露给外部使用,但是我们使用的ingress规则都是落在istio部署时默认创建的istio-ingressgateway上,如果我们希望创建自定义的ingressgateway该怎么操作呢,本文就带大家一步步操作,创建一个自定义的ingressgateway 环境准备 创建Kubernetes集群 阿里云容器服务Kubernetes 1.11.2目前已经上线,可以通过容器服务管理控制台非常方便地快速创建 Kubernetes 集群。
6158 0
|
网络协议 Ubuntu Linux
飞腾CPU如何使用PXE方式安装麒麟桌面系统?
飞腾CPU如何使用PXE方式安装麒麟桌面系统?
4543 0
飞腾CPU如何使用PXE方式安装麒麟桌面系统?