【优选算法】(第七篇)

目录

⽔果成篮(medium)

题目解析

讲解算法原理

编写代码

找到字符串中所有字⺟异位词(medium)

题目解析

讲解算法原理

编写代码


⽔果成篮(medium)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

你正在探访⼀家农场,农场从左到右种植了⼀排果树。这些树⽤⼀个整数数组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=[3,3,3,1,2,1,1,2,3,3,4]输出:5
解释:
可以采摘[1,2,1,1,2]这五棵树。

讲解算法原理

解法(滑动窗⼝):算法思路:
研究的对象是⼀段连续的区间,可以使⽤「滑动窗⼝」思想来解决问题。让滑动窗⼝满⾜:窗⼝内⽔果的种类只有两种。
做法:右端⽔果进⼊窗⼝的时候,⽤哈希表统计这个⽔果的频次。这个⽔果进来后,判断哈希表的⼤⼩:
▪ 如果⼤⼩超过2:说明窗⼝内⽔果种类超过了两种。那么就从左侧开始依次将⽔果划出窗
⼝,直到哈希表的⼤⼩⼩于等于2,然后更新结果;
▪ 如果没有超过2,说明当前窗⼝内⽔果的种类不超过两种,直接更新结果ret。
算法流程:
a. 初始化哈希表hash来统计窗⼝内⽔果的种类和数量;
b. 初始化变量:左右指针left=0,right=0,记录结果的变量ret=0;c. 当right⼩于数组⼤⼩的时候,⼀直执⾏下列循环:
i. 将当前⽔果放⼊哈希表中;
ii. 判断当前⽔果进来后,哈希表的⼤⼩:
• 如果超过2:
◦ 将左侧元素滑出窗⼝,并且在哈希表中将该元素的频次减⼀;◦ 如果这个元素的频次减⼀之后变成了0,就把该元素从哈希表中删除;◦ 重复上述两个过程,直到哈希表中的⼤⼩不超过2;
iii. 更新结果ret;
iv. right++,让下⼀个元素进⼊窗⼝;
d. 循环结束后,ret存的就是最终结果。

如图所示:

可以利用left和right双指针,此时需要一个统计数kinds去记录这个区间水果的种类,当kinds不超过2时right向右进行移动,便是利用hash思想,如果说超过便停止,此时移动left,这是只需要用双指针将整个数组遍历一遍(这里用数组不用hash是因为题目给的范围用数组会更高效,范围比较小如果用hash反而一直进出,时间复杂度会变高),那么整个题的时间复杂度便非常可观! 

编写代码

c++算法代码(使用容器):

class Solution
{
public:
 int totalFruit(vector<int>& f) 
 {
 unordered_map<int, int> hash; // 统计窗⼝内出现了多少种⽔果 int ret = 0;
 for(int left = 0, right = 0; right < f.size(); right++)
 {
 hash[f[right]]++; // 进窗⼝
 while(hash.size() > 2) // 判断
 {
 // 出窗⼝
 hash[f[left]]--;
 if(hash[f[left]] == 0)
 hash.erase(f[left]);
 left++;
 }
 ret = max(ret, right - left + 1);
 }
 return ret;
 }
};

c++算法代码(用数组模拟哈希表):

class Solution
{
public:
 int totalFruit(vector<int>& f) 
 {
 int hash[100001] = { 0 }; // 统计窗⼝内出现了多少种⽔果
 int ret = 0;
 for(int left = 0, right = 0, kinds = 0; right < f.size(); right++)
 {
 if(hash[f[right]] == 0) kinds++; // 维护⽔果的种类
 hash[f[right]]++; // 进窗⼝
 while(kinds > 2) // 判断
 {
 // 出窗⼝
 hash[f[left]]--;
 if(hash[f[left]] == 0) kinds--;
 left++;
 }
 ret = max(ret, right - left + 1);
 }
 return ret;
 }
};

 java算法代码(使用容器):

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;
 }
}

java算法代码(用数组模拟哈希表):

class Solution
{
 public int totalFruit(int[] f) 
 {
 int n = f.length;
 int[] hash = new int[n + 1]; // 统计窗⼝内⽔果的种类
 int ret = 0;
 for(int left = 0, right = 0, kinds = 0; right < n; right++)
 {
 int in = f[right];
 if(hash[in] == 0) kinds++; // 维护⽔果种类
 hash[in]++; // 进窗⼝
 while(kinds > 2) // 判断
 {
 int out = f[left];
 hash[out]--; // 出窗⼝
 if(hash[out] == 0) kinds--;
 left++;
 }
 // 更新结果
 ret = Math.max(ret, right - left + 1);
 }
 return ret;
 }
}

找到字符串中所有字⺟异位词(medium)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

给定两个字符串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*10^4
s和p仅包含⼩写字⺟

讲解算法原理

解法(滑动窗⼝+哈希表):
算法思路:
◦ 因为字符串 p 的异位词的⻓度⼀定与字符串 p 的⻓度相同,所以我们可以在字符串 s 中构
造⼀个⻓度为与字符串 p 的⻓度相同的滑动窗⼝,并在滑动中维护窗⼝中每种字⺟的数量;◦ 当窗⼝中每种字⺟的数量与字符串 p 中每种字⺟的数量相同时,则说明当前窗⼝为字符串 p
的异位词;
◦ 因此可以⽤两个⼤⼩为 26 的数组来模拟哈希表,⼀个来保存 s 中的⼦串每个字符出现的个
数,另⼀个来保存 p 中每⼀个字符出现的个数。这样就能判断两个串是否是异位词。

 

编写代码

c++算法代码:

class Solution
{
public:
 vector<int> findAnagrams(string s, string p) 
 {
 vector<int> ret;
 int hash1[26] = { 0 }; // 统计字符串 p 中每个字符出现的个数
 for(auto ch : p) hash1[ch - 'a']++;
 int hash2[26] = { 0 }; // 统计窗⼝⾥⾯的每⼀个字符出现的个数
 int m = p.size();
 for(int left = 0, right = 0, count = 0; right < s.size(); right++)
 {
 char in = s[right];
 // 进窗⼝ + 维护 count
 if(++hash2[in - 'a'] <= hash1[in - 'a']) count++; 
 if(right - left + 1 > m) // 判断
 {
 char out = s[left++];
 // 出窗⼝ + 维护 count
 if(hash2[out - 'a']-- <= hash1[out - 'a']) count--; 
 }
 // 更新结果
 if(count == m) ret.push_back(left);
 }
 return ret;
 }
};

java算法代码:

class Solution
{
 public List<Integer> findAnagrams(String ss, String pp) 
 {
 List<Integer> ret = new ArrayList<Integer>();
 char[] s = ss.toCharArray();
 char[] p = pp.toCharArray();
 int[] hash1 = new int[26]; // 统计字符串 p 中每⼀个字符出现的个数 
 for(char ch : p) hash1[ch - 'a']++;
 int[] hash2 = new int[26]; // 统计窗⼝中每⼀个字符出现的个数
 int m = p.length;
 for(int left = 0, right = 0, count = 0; right < s.length; right++)
 {
 char in = s[right];
 // 进窗⼝ + 维护 count
 if(++hash2[in - 'a'] <= hash1[in - 'a']) count++; 
 if(right - left + 1 > m) // 判断
 {
 char out = s[left++];
 // 出窗⼝ + 维护 count
 if(hash2[out - 'a']-- <= hash1[out - 'a']) count--; 
 }
 // 更新结果
 if(count == m) ret.add(left);
 }
 return ret;
 }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/884338.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

神经网络(一):神经网络入门

文章目录 一、神经网络1.1神经元结构1.2单层神经网络&#xff1a;单层感知机1.3两层神经网络&#xff1a;多层感知机1.4多层神经网络 二、全连接神经网络2.1基本结构2.2激活函数、前向传播、反向传播、损失函数2.2.1激活函数的意义2.2.2前向传播2.2.3损失函数、反向传播2.2.4梯…

连锁店收银系统如何选择?

在新零售背景下&#xff0c;连锁店的收银系统扮演着至关重要的角色。随着科技的不断发展和消费者需求的不断变化&#xff0c;一款功能齐全的收银系统不仅可以提高便利店的运营效率&#xff0c;还可以提供更好的消费体验。以下是连锁店收银系统必备的功能。 1.收银系统能支持独…

Mac制作Linux操作系统启动盘

前期准备 一个 Mac 电脑 一个 U 盘&#xff08;8GB 以上&#xff09; 下载好 Linux 系统镜像&#xff08;iso 文件&#xff09; 具体步骤 挂载 U 盘 解挂 U 盘 写系统镜像到 U 盘 完成 一、挂载 U 盘 首先插入 U 盘&#xff0c;打开终端输入下面的命令查看 U 盘是否已经 m…

python单例和工厂模式

设计模式 设计模式是一种编程套路&#xff0c;可以极大的方便程序的开发 最常见、最经典的设计模式&#xff0c;就是学习的面向对象 除了面向对象之外&#xff0c;在编程中也有很多既定的套路可以方便开发&#xff0c;我们称之为设计模式&#xff1a; 单例、工厂模式建造者…

IDEA2020运行项目时不从配置的maven仓库找jar包,从C盘默认路径下找jar包

目录 问题描述&#xff1a; 解决方案&#xff1a; 问题描述&#xff1a; 使用IDEA2020做java开发&#xff0c;idea的设置中maven仓库地址配在D盘&#xff0c; maven的配置文件setting.xml中的仓库也已经确认配置到D盘&#xff0c; 项目根据pom文件自动下载jar包时也会下载到…

IDEA 系列产品 下载

准备工作 下载 下载链接&#xff1a;https://www.123865.com/ps/EF7OTd-mbHnH 仅供参考 环境 演示环境&#xff1a; 操作系统&#xff1a;windows10 产品&#xff1a;IntelliJ IDEA 版本&#xff1a;2024.1.2 注意&#xff1a;如果需要其他产品或者版本可以自行下载&#xff0…

【算法系列-数组】移除元素 (双指针)

【算法系列-数组】移除元素 (双指针) 文章目录 【算法系列-数组】移除元素 (双指针)1. 算法分析&#x1f6f8;2. 删除有序数组中的重复性(LeetCode 26)2.1 解题思路&#x1f3af;2.2 解题过程&#x1f3ac;2.3 代码举例&#x1f330; 3. 移动零(LeetCode 283)3.1 解题思路&…

黑马智数Day4-1

新增月卡 配置路由完成跳转 {path: /cardAdd,component: () > import(/views/car/car-card/add-card) }<el-button type"primary" click"$router.push(/cardAdd)">添加月卡</el-button> 车辆信息表单验证 <el-form :model"carInf…

【移植】一种快速移植OpenHarmony Linux内核的方法

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 移植概述 本文面向希望将 OpenHarmony 移植到三方芯片平台硬件的开…

接档《凡人修仙传》的《牧神记》动画,能否成为黑马?

堪称B站国创半边天的《凡人修仙传》第三季将在10月19日迎来完结&#xff0c;接档它的是由玄机科技制作&#xff0c;改编自宅猪同名网络小说的《牧神记》。这部将于10月27日播出的“玄机娘娘新崽”&#xff0c;能否成功接下《凡人修仙传》的好彩头&#xff0c;成为国漫界下一匹黑…

LeetCode[中等] 78.子集

给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的 子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 思路 迭代法 每次遍历nums中的新的数&#xff0c;将其加到之前所有得到的set中&#xff0c…

【第十六章:Sentosa_DSML社区版-机器学习之生存分析】

【第十六章&#xff1a;Sentosa_DSML社区版-机器学习之生存分析】 16.1 加速失效时间回归 1.算子介绍 加速失效时间回归模型Accelerated failure time (AFT)是一个监督型参数化的回归模型&#xff0c;它可以处理删失数据。它描述了一个生存时间的对数模型&#xff0c;所以它通…

深度解读 2024 Gartner DevOps 魔力象限

上周 Gartner 刚发布了 2024 年度的 DevOps 魔力象限。我们也第一时间来深度解读一下这份行业里最权威的报告。 和2023年对比 23 年入围 14 家厂商&#xff0c;24 年入围 11 家。4 家厂商从报告中消失&#xff0c;分别是 Bitrise, Codefresh, Google Cloud Platform (GCP), VM…

SpringBoot集成Redis及SpringCache缓存管理

1.集成Redis 1.导入依赖 <!--spirngboot springdata对redis支持--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 2.配置信息 #数据源配置…

服务器端请求伪造(SSRF)漏洞解析

免责申明 本文仅是用于学习检测自己搭建的靶场环境有关SSRF的原理和攻击实验,请勿用在非法途径上,若将其用于非法目的,所造成的一切后果由您自行承担,产生的一切风险和后果与笔者无关;本文开始前请认真详细学习《‌中华人民共和国网络安全法》‌及其所在国家地区相关法规内…

欺诈文本分类检测(十七):支持分类原因训练

1. 引言 前文数据校正与增强进行了数据增强&#xff0c;本文将使用增强后的数据对模型进行进一步训练&#xff0c;以便得到能同时预测出分类标签、欺诈者、分类原因多个信息的模型。 为此&#xff0c;我们需要对整个训练过程进行调整&#xff0c;包括&#xff1a; 交叉训练逻…

3-1.Android Fragment 之创建 Fragment

Fragment Fragment 可以视为 Activity 的一个片段&#xff0c;它具有自己的生命周期和接收事件的能力&#xff0c;它有以下特点 Fragment 依赖于 Activity&#xff0c;不能独立存在&#xff0c;Fragment 的生命周期受 Activity 的生命周期影响 Fragment 将 Activity 的 UI 和…

信安 实验1 用Wireshark分析典型TCP/IP体系中的协议

我发现了有些人喜欢静静看博客不聊天呐&#xff0c; 但是ta会点赞。 这样的人呢帅气低调有内涵&#xff0c; 美丽大方很优雅。 说的就是你&#xff0c; 不用再怀疑哦 实验1 用Wireshark分析典型TCP/IP体系中的协议 实验目的 通过Wireshark软件分析典型网络协议数据包&a…

C++深入学习string类成员函数(3):访问与修饰

引言 在 C 中&#xff0c;std::string 提供了丰富的成员函数来访问和修改字符串中的字符。通过这些函数&#xff0c;程序员可以灵活地处理字符串中的各个元素&#xff0c;无论是读取特定位置的字符&#xff0c;还是修改字符串的内容。此外&#xff0c;std::string 类还确保了访…

FileZilla Server 黑白单移除

我使用FileZilla Server 搭建了一个FTP服务在内网使用&#xff0c;主要用于做数据备份的。 有一台服务器一直可以正常连接&#xff0c;突然有一天不能连接了。一开始我以为是FTP服务器出问题了&#xff0c;就一直没管。后来我测试了一下其他IP都可以正常连接FTP服务器&#xff…