【优选算法】Sliding-Chakra:滑动窗口的算法流(下)

【优选算法】Sliding-Chakra:滑动窗口的算法流(下)

文章目录

本篇接上一篇滑动窗口算法,这一篇有些许难度,为了提升自我,请耐心看完后,多敲代码整理思路,相信能够有莫大的收获😼

1.水果成篮

✏️题目描述:

在这里插入图片描述

✏️示例:

在这里插入图片描述
传送门:水果成篮

题解:

首先解读题意,简单来说就是找到一个区间,其中的果树种类用数字表示,种类不超过两种,题目默认是能找到至少两种水果,所以求在此前提下能找到的最长区间是多少?

在这里插入图片描述

💻第一步:

或许该题可以使用暴力解法解决,但明显时间复杂度太高无法通过示例
因此根据前些题目的经验,由于是找区间,而且要统计种类数量滑动窗口+哈希表

在这里插入图片描述

💻第二步:

具体的窗口滑动如图所示

在这里插入图片描述

先让第一个数据录入,即进窗口判断不断循环,然后right依次向后移并不断往哈希表录入每个位置种类更新数据,直到哈希表内的键值对大于2,即种类大于2;此时left减去第一个数据,即出窗口判断不断循环,然后不断向后移直到哈希表里的一个种类数据变为0,对其进行erase操作减少一个种类,再次开始更新数据

💻代码实现:

#include<iostream>#include<vector>#include<unordered_map>usingnamespace std;classSolution{public:inttotalFruit(vector<int>& fruits){ unordered_map<int,int> hash;int ret =0, n = fruits.size();for(int left =0, right =0; right < n;++right){ hash[fruits[right]]++;while(hash.size()>2){ hash[fruits[left]]--;if(hash[fruits[left]]==0){ hash.erase(fruits[left]);} left++;} ret =max(ret, right - left +1);}return ret;}};

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

✏️题目描述:

在这里插入图片描述

✏️示例:

在这里插入图片描述
传送门:找到字符串中所有字母异位词

题解:

首先我们要知道什么是异位词?

在这里插入图片描述

本题第一难为解读题意,通常读不懂题目时要多结合示例分析,结合示例1示例2,把p这个字符串放在s这个字符串里比对,不考虑p的顺序,找到所有异位词,返回其起始下标

在这里插入图片描述

💻第一步:

先思考如何在代码运行过程中判断其是否为异位词,只判断个数显然是不行的,既要种类相同,又要出现的个数相同,因为哈希表会减慢运行,这里也只有26种字母,所以我们可以给需要找到的字符串创建模拟哈希表hash1被寻找的字符串创建模拟哈希表hash2对比两个哈希表的种类及数量就能准确得出是否为异位词

在这里插入图片描述

💻第二步:

具体实现的流程图如图所示,与前些写的题有些许不同

在这里插入图片描述

先让第一个数据录入,即进窗口判断不断循环,然后right依次向后移并不断往哈希表中录入,直到left和right之间的长度大于字符串p;此时left减去第一个数据,即出窗口判断不断循环,然后向后移1位使长度继续维持为字符串pcheck然后如果符合要求则更新结果。然后right向前一位,判断,left向前一位,判断更新结果,以此循环

💻细节问题

这里重点在于如何更新结果,一般的思路是遍历hash1和hash2,并对比两个数组,显然此方法是冗余复杂的,接下来将介绍一种方法,通常想不到,因此很有学习价值

在这里插入图片描述

先统计字符串p中的字符种类及数量,count表示sleftright之间的种类数量,在right移动过程中,字符串s的起始种类数量都为0,然后当字符串s的种类数量小于等于字符串p的种类数量时,说明该位置增加的是有效字符,count++

在这里插入图片描述

还是滑动窗口的起始操作,如图当righte时,明显超出了字符串p的大小,left应该在c,移动leftb,然后当字符串s的种类数量小于等于字符串p的种类数量时,说明该位置减少的是有效字符,count--

请添加图片描述

最后当两个模拟哈希表中的种类数量相等,即count == m

💻代码实现:

#include<iostream>#include<vector>usingnamespace std;classSolution{public: vector<int>findAnagrams(string s, string p){ vector<int> ret;int hash1[26]={0};for(auto ch : p){ hash1[ch -'a']++;}int hash2[26]={0};int n = s.size();int m = p.size();for(int left =0, right =0, count =0; right < n;++right){ hash2[s[right]-'a']++;if(hash2[s[right]-'a']<= hash1[s[right]-'a']){ count++;}if(right - left +1> m){if(hash2[s[left]-'a']<= hash1[s[left]-'a']){ count--;} hash2[s[left]-'a']--; left++;}if(count == m){ ret.push_back(left);}}return ret;}};

3.串联所有单词的子串

✏️题目描述:

在这里插入图片描述

✏️示例:

在这里插入图片描述
传送门:串联所有单词的子串

题解:

本题的题意也有些难以理解,但是结合找到字符串中所有字母异位词这题的铺垫,使得这题也不是无从下手

在这里插入图片描述

如图所示,把这些字符串看成一个个的字符,是不是就和之前那题是一样的?

💻细节问题

w每个字符串的长度多长,那么left,right就有几种起始情况

在这里插入图片描述

当right移动到最后不足字符串w的长度时,会发生越界,所以要写为right + len <= n

在这里插入图片描述

💻代码实现:

#include<iostream>#include<vector>#include<unordered_map>usingnamespace std;classSolution{public: vector<int>findSubstring(string s, vector<string>& words){ unordered_map<string,int> hash1;for(auto s : words){ hash1[s]++;} vector<int> ret;int len = words[0].size(), m = words.size(), n = s.size();for(int i =0; i < len;++i){ unordered_map<string,int> hash2;for(int left = i, right = i, count =0; right + len <= n; 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){ ret.push_back(left);}}}return ret;}};

4.最小覆盖子串

✏️题目描述:

在这里插入图片描述

✏️示例:

在这里插入图片描述
传送门:最小覆盖子串

题解:

本题题意为在字符串s里找到一个含有t的字符串区间,只要该区间内符合t的种类数量即可,无论其他的字符有多少个

在这里插入图片描述

💻细节问题

所以本题虽说是困难难度,但是依据前几题的思路铺垫,这道题也能说不在话下了,依旧是模拟哈希表+滑动窗口(因为哈希表太占空间了,影响效率)

在这里插入图片描述

注意当是当hash2中的种类数量hash1中的种类数量一样时才count++

💻代码实现:

#include<iostream>#include<string>usingnamespace std;classSolution{public: string minWindow(string s, string t){int hash1[128]={0};int kinds =0;for(auto ch : t){if(hash1[ch]++==0){ kinds++;}}int hash2[128]={0};int n = s.size(), minlen = INT_MAX, begin =-1;for(int left =0, right =0, count =0; right < n;++right){if(++hash2[s[right]]== hash1[s[right]]){ count++;}while(count == kinds){if(right - left +1< minlen){ minlen = right - left +1; begin = left;}if(hash2[s[left]]--== hash1[s[left]]){ count--;} left++;}}if(begin ==-1){return"";}else{return s.substr(begin, minlen);}}};
在这里插入图片描述

也是第一次用时击败100%,比官方还优秀的解法😎


希望读者们多多三连支持

小编会继续更新

你们的鼓励就是我前进的动力!

请添加图片描述

Read more

Flutter 组件 shelf_router 的适配 鸿蒙Harmony 实战 - 驾驭官方标准路由器架构、实现鸿蒙端 HTTP 流量精密分发与逻辑路由审计方案

Flutter 组件 shelf_router 的适配 鸿蒙Harmony 实战 - 驾驭官方标准路由器架构、实现鸿蒙端 HTTP 流量精密分发与逻辑路由审计方案

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 shelf_router 的适配 鸿蒙Harmony 实战 - 驾驭官方标准路由器架构、实现鸿蒙端 HTTP 流量精密分发与逻辑路由审计方案 前言 在鸿蒙(OpenHarmony)生态的分布式业务中继、政务级内嵌 API 管理平台以及需要承载大规模高频交互请求的各类全栈式应用开发中,“路由的精确支配与逻辑安全性”是决定系统架构稳健性的命门所在。面对包含上百个 RESTful 端点的复杂服务模型、需要动态解析包含 UUID、日期等多种格式的 URL 参数,或者是需要针对鸿蒙手机与智慧大屏执行差异化的路由匹配。如果仅仅依靠原始的字符串拆分或低性能的手写拦截逻辑。不仅会导致路由解析执行效率的低下,更会因为缺乏一套工业级的“官方契约”规范。引发鸿蒙端微服务接口在面对异常报文时的逻辑脆弱性风险。 我们需要一种“官方背书、匹配闭环”的路由艺术。 shelf_router 是一套由 Dart 官方团队维护的、

By Ne0inhk
【MYSQL】MYSQL学习的一大重点:数据库基础

【MYSQL】MYSQL学习的一大重点:数据库基础

🎬 个人主页:艾莉丝努力练剑 ❄专栏传送门:《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录》 《Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享》 ⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平 🎬 艾莉丝的简介: 文章目录 * 1 ~> 数据库概念 * 2 ~> 当前主流的数据库 * 3 ~> MYSQL的基本使用 * 3.1 MYSQL的安装 * 3.2 连接服务器 * 3.3 服务器管理 * 3.4 服务器,数据库,表关系 * 3.5 使用案例(文章最后有详细流程) * 3.6

By Ne0inhk
【MySQL数据库基础】(六)MySQL 表的约束详解:从基础到实战,拿捏数据合法性!

【MySQL数据库基础】(六)MySQL 表的约束详解:从基础到实战,拿捏数据合法性!

前言         在 MySQL 数据库开发中,我们总希望存入表中的数据是合法、规范、符合业务逻辑的。虽然数据类型能对字段做基础限制,但面对复杂的业务需求,仅靠数据类型远远不够。比如要求邮箱唯一、用户名不能为空、学生的班级必须是已存在的班级…… 这些需求都需要靠表的约束来实现。         表的约束是数据库保证数据完整性的核心手段,它能从业务逻辑层面过滤无效数据,避免脏数据进入数据库。今天这篇文章就带大家全面吃透 MySQL 中最常用的表约束,包括null/not null、default、comment、zerofill、primary key、auto_increment、unique key、foreign key,从基础概念到实操案例,手把手教你用约束拿捏数据合法性!下面就让我们正式开始吧! 一、为什么需要表的约束?         先看一个简单的例子:如果我们创建一个班级表,只定义字段和数据类型,不添加任何约束,会发生什么? -- 无约束的班级表 create table myclass( class_

By Ne0inhk
绿联云NAS配置webdav

绿联云NAS配置webdav

前言         zotero使用webdav服务时使用绿联自带的webdav服务只能使用http协议,并且只能在局域网内传输,故而尝试自行配置,以期实现公网文献同步。 注:非专业,自己在配置的时候也是根据前人的分享实现的,可能有很多不准确的地方,请见谅。 1. 大致思路         购买域名(腾讯云)→配置DDNS-go(docker)→获取SSL证书(乐此加密)→配置natfrp(docker) ①域名:固定域名,后续内网穿透时可以使用自定义域名; ②DDNS-go:自动更新域名解析到公网IP; ③SSL证书:https协议需要; ④natfrp:内网穿透需要,这里使用的是Sakura Frp。 2.参考文献 (31 封私信 / 80 条消息) 绿联 NAS 域名直连 DDNS-Go+IPv6 内网穿透并开启 HTTPS - 知乎https://zhuanlan.zhihu.com/p/

By Ne0inhk