【优选算法】(第五篇)

news2024/9/27 15:16:16

目录

⻓度最⼩的⼦数组(medium)

题目解析

讲解算法原理

编写代码

⽆重复字符的最⻓⼦串(medium)

题目解析

讲解算法原理

编写代码


⻓度最⼩的⼦数组(medium)

题目解析

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

2.题目描述

给定⼀个含有 n 个正整数的数组和⼀个正整数 target 。
找出该数组中满⾜其和 ≥ target 的⻓度最⼩的连续⼦数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其⻓度。如果不存在符合条件的⼦数组,返回0。
⽰例1:
输⼊: target = 7, nums = [2,3,1,2,4,3]
输出: 2
解释:
⼦数组 [4,3] 是该条件下的⻓度最⼩的⼦数组。
⽰例2:
输⼊: target = 4, nums = [1,4,4]
输出: 1
⽰例3:
输⼊: target = 11, nums = [1,1,1,1,1,1,1,1]
输出: 0

讲解算法原理

解法⼀(暴⼒求解)(会超时):
算法思路:
「从前往后」枚举数组中的任意⼀个元素,把它当成起始位置。然后从这个「起始位置」开始,然后寻找⼀段最短的区间,使得这段区间的和「⼤于等于」⽬标值。
将所有元素作为起始位置所得的结果中,找到「最⼩值」即可。

算法代码:

class Solution {
public:
 int minSubArrayLen(int target, vector<int>& nums) {
 // 记录结果
 int ret = INT_MAX;
 int n = nums.size();
 // 枚举出所有满⾜和⼤于等于 target 的⼦数组[start, end] // 由于是取到最⼩,因此枚举的过程中要尽量让数组的⻓度最⼩ // 枚举开始位置
 for (int start = 0; start < n; start++)
 {
 int sum = 0; // 记录从这个位置开始的连续数组的和 // 寻找结束位置
 for (int end = start; end < n; end++)
 {
 sum += nums[end]; // 将当前位置加上
 
 if (sum >= target) // 当这段区间内的和满⾜条件时 {
 // 更新结果,start 开头的最短区间已经找到 ret = min(ret, end - start + 1);
 break;
 }
 }
 }
 // 返回最后结果
 return ret == INT_MAX ? 0 : ret;
 }
};

解法⼆(滑动窗⼝):
算法思路:
由于此问题分析的对象是「⼀段连续的区间」,因此可以考虑「滑动窗⼝」的思想来解决这道题。让滑动窗⼝满⾜:从 i 位置开始,窗⼝内所有元素的和⼩于 target (那么当窗⼝内元素之和
第⼀次⼤于等于⽬标值的时候,就是 i 位置开始,满⾜条件的最⼩⻓度)。做法:将右端元素划⼊窗⼝中,统计出此时窗⼝内元素的和:
▪ 如果窗⼝内元素之和⼤于等于 target :更新结果,并且将左端元素划出去的同时继续判
断是否满⾜条件并更新结果(因为左端元素可能很⼩,划出去之后依旧满⾜条件)▪ 如果窗⼝内元素之和不满⾜条件: right++ ,另下⼀个元素进⼊窗⼝。
相信科学(这也是很多题解以及帖⼦没告诉你的事情:只给你说怎么做,没给你解释为什么这么做):
为何滑动窗⼝可以解决问题,并且时间复杂度更低?
▪ 这个窗⼝寻找的是:以当前窗⼝最左侧元素(记为 left1 )为基准,符合条件的情况。也
就是在这道题中,从 left1 开始,满⾜区间和 sum >= target 时的最右侧(记为
right1 )能到哪⾥。
▪ 我们既然已经找到从 left1 开始的最优的区间,那么就可以⼤胆舍去 left1 。但是如
果继续像⽅法⼀⼀样,重新开始统计第⼆个元素( left2 )往后的和,势必会有⼤量重复的计算(因为我们在求第⼀段区间的时候,已经算出很多元素的和了,这些和是可以在计算下次区间和的时候⽤上的)。
▪ 此时, rigth1 的作⽤就体现出来了,我们只需将 left1 这个值从 sum 中剔除。从
right1 这个元素开始,往后找满⾜ left2 元素的区间(此时 right1 也有可能是满
⾜的,因为 left1 可能很⼩。 sum 剔除掉 left1 之后,依旧满⾜⼤于等于
target )。这样我们就能省掉⼤量重复的计算。
▪ 这样我们不仅能解决问题,⽽且效率也会⼤⼤提升。
时间复杂度:虽然代码是两层循环,但是我们的 left 指针和 right 指针都是不回退的,两者最多都往后移动 n 次。因此时间复杂度是 O(N) 。

 

如图所示:

在left每次加加的时候,减去前一个left值,这样right就不需要再返回来进行一个运算,大大节省了空间复杂度 

编写代码

c++算法代码:

class Solution
{
public:
 int minSubArrayLen(int target, vector<int>& nums) 
 {
 int n = nums.size(), sum = 0, len = INT_MAX;
 for(int left = 0, right = 0; right < n; right++)
 {
 sum += nums[right]; // 进窗⼝
 while(sum >= target) // 判断
 {
 len = min(len, right - left + 1); // 更新结果
 sum -= nums[left++]; // 出窗⼝
 }
 }
 return len == INT_MAX ? 0 : len;
 }
};

java算法代码:

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

⽆重复字符的最⻓⼦串(medium)

题目解析

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

2.题目讲解

给定⼀个字符串s,请你找出其中不含有重复字符的最⻓⼦串的⻓度。
⽰例1:
输⼊: s = "abcabcbb"
输出: 3
解释:因为⽆重复字符的最⻓⼦串是 "abc" ,所以其⻓度为 3 。⽰例2:
输⼊: s = "bbbbb"
输出: 1
解释:因为⽆重复字符的最⻓⼦串是 "b" ,所以其⻓度为 1 。⽰例3:
输⼊: s = "pwwkew"
输出: 3
解释:因为⽆重复字符的最⻓⼦串是 "wke" ,所以其⻓度为 3 。请注意,你的答案必须是⼦串的⻓度, "pwke" 是⼀个⼦序列,不是⼦串。

提⽰:
• 0 <= s.length <= 5 * 10^4
• s 由英⽂字⺟、数字、符号和空格组成1.

讲解算法原理

解法⼀(暴⼒求解)(不会超时,可以通过):
算法思路:
枚举「从每⼀个位置」开始往后,⽆重复字符的⼦串可以到达什么位置。找出其中⻓度最⼤的即可。
在往后寻找⽆重复⼦串能到达的位置时,可以利⽤「哈希表」统计出字符出现的频次,来判断什么时候⼦串出现了重复元素。

算法代码:

class Solution {
public:
 int lengthOfLongestSubstring(string s) {
 int ret = 0; // 记录结果
 int n = s.length();
 // 1. 枚举从不同位置开始的最⻓重复⼦串
 // 枚举起始位置
 for (int i = 0; i < n; i++)
 {
 // 创建⼀个哈希表,统计频次
 int hash[128] = { 0 };
 
 // 寻找结束为⽌
 for (int j = i; j < n; j++)
 {
 hash[s[j]]++; // 统计字符出现的频次 if (hash[s[j]] > 1) // 如果出现重复的
 break;
 
 // 如果没有重复,就更新 ret
 ret = max(ret, j - i + 1);
 }
 }
 // 2. 返回结果
 return ret;
 }
};

解法⼆(滑动窗⼝):
算法思路:
研究的对象依旧是⼀段连续的区间,因此继续使⽤「滑动窗⼝」思想来优化。让滑动窗⼝满⾜:窗⼝内所有元素都是不重复的。
做法:右端元素 ch 进⼊窗⼝的时候,哈希表统计这个字符的频次:
▪ 如果这个字符出现的频次超过 1 ,说明窗⼝内有重复元素,那么就从左侧开始划出窗⼝,
直到 ch 这个元素的频次变为 1 ,然后再更新结果。▪ 如果没有超过 1 ,说明当前窗⼝没有重复元素,可以直接更新结果 

如图所示:
在出现重复字符之后,left一直移动到重复字符之后,这样的话left可以进行一次小优化,并且整个数组只需要遍历一次,时间复杂度非常可观! 

编写代码

c++算法代码:

class Solution
{
public:
 int lengthOfLongestSubstring(string s) 
 {
 int hash[128] = { 0 }; // 使⽤数组来模拟哈希表 int left = 0, right = 0, n = s.size();
 int ret = 0;
 while(right < n)
 {
 hash[s[right]]++; // 进⼊窗⼝
 while(hash[s[right]] > 1) // 判断
 hash[s[left++]]--; // 出窗⼝
 ret = max(ret, right - left + 1); // 更新结果 right++; // 让下⼀个元素进⼊窗⼝
 }
 return ret;
 }
};

java算法代码:

class Solution
{
 public int lengthOfLongestSubstring(String ss) 
 {
 char[] s = ss.toCharArray();
 int[] hash = new int[128]; // ⽤数组模拟哈希表 int left = 0, right = 0, n = ss.length();
 int ret = 0;
 while(right < n)
 {
 hash[s[right]]++; // 进⼊窗⼝
 while(hash[s[right]] > 1) // 判断
 hash[s[left++]]--; // 出窗⼝
 ret = Math.max(ret, right - left + 1); // 更新结果 right++; // 让下⼀个字符进⼊窗⼝
 }
 return ret;
 }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分割数组的最大值

题目链接 分割数组的最大值 题目描述 注意点 0 < nums[i] < 10^61 < nums.length < 10001 < k < min(50, nums.length) 解答思路 首先需要理解题意&#xff0c;需要将这个数组分成 k 个非空的连续子数组&#xff0c;找到划分组合中子数组和的最大值最小…

el-table+el-form实现表单校验和解决不垂直居中导致的问题

el-tableel-form实现表单校验 1.实现el-table的表单校验 关键点123 2.解决不垂直居中导致的问题 问题效果图 解决方案 .item-align-center {display: inline-flex; }

OJ在线评测系统 原生Java代码沙箱核心实现流程三 整理封装输出结果 拿到程序执行时间(stopwatch类) 和 运行内存

我们在之前的操作中已经拿到程序进行了编译和运行 接下来我们要将我们的结果输出 整理输出 // 4.收集整理输出结果 ExecuteCodeResponse executeCodeResponse new ExecuteCodeResponse(); ArrayList<String> outputList new ArrayList<>();for (ExecuteMessage…

Library介绍(一)

之前和大家介绍过cell delay是如何计算的。那么&#xff0c;本文将着重和大家介绍一些timing lib中的各个参数定义是什么意思。会分以下几个部分介绍&#xff1a;库属性描述、时序弧介绍、环境描述、单元描述。之前介绍的cell delay template就是单元描述中的一部分。本文主要介…

网络安全入门必备:这四点你做到了吗?

数据的鸿沟无疑是显而易见的&#xff0c;网络安全领域亟需熟练的专业人员。 组织在这方面投入巨大资金&#xff0c;但挑战依旧存在。 根据最新的研究&#xff0c;有64%的违规行为是导致机构过去一年收入损失及/或罚款的主要原因。 60%的组织在努力招聘网络安全人才&#xff…

【市场解读】新能源汽车换代问题

参考文献&#xff1a;百分点舆情中心《新能源汽车换代问题消费者情绪洞察报告》 行业背景 新能源汽车市场竞争加剧&#xff0c;车企不断推陈出新政府发布《汽车以旧换新补贴实施细则》&#xff0c;激励市场发展 *对汽车换代问题媒体关注度与网友讨论度高&#xff0c;正面声量…

电脑退域后系统黑屏

之前加入域时迁移了账号系统&#xff0c;导致退域后本地账号系统没了东西黑屏但能看到鼠标。也登不了域账号了一顿慌张&#xff08;操作如下&#xff09; 解决&#xff1a;又加回了域哈哈哈 重启电脑按F8进不去安全模式&#xff0c;找不到触发时间... winr打开运行&#xff0c;…

都说网络安全缺口那么大,但为何招聘数量却不多?总算明白了!

为啥网安领域缺口多达300多万人&#xff0c;但网安工程师也就是白帽黑客却很少&#xff0c;难道又是砖家在忽悠人&#xff1f; 原因主要为这三点: 首先是学校的原因&#xff0c;很多学校网络安全课程用的还都是十年前的老教材&#xff0c;教学脱离社会需求&#xff0c;实操技能…

【Python报错已解决】TypeError: expected Tensor as element 1 in argument 0, but got int

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

NHANES数据(复杂调查数据)亚组交互函数2.3版(P for interaction)发布---用于一键生成交互效应表

写在前面的话&#xff0c;本函数只支持NHANES数据(复杂调查数据)的逻辑回归和线性回归&#xff0c;其他类型均不支持&#xff0c;请注意甄别&#xff0c;电子产品&#xff0c;买错不能退换。 在SCI文章中&#xff0c;交互效应表格&#xff08;通常是表五&#xff09;能为文章锦…

多类别物体检测系统源码分享

多类别物体检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer V…

“领航猿1号” 正式更名为 “AGI舰长”

亲爱的朋友们&#xff0c;很高兴的告诉大家&#xff1a; 我各个平台的账号昵称正式 由“领航猿1号” 更名为 “AGI舰长” 为什么更名&#xff1a; 为了更好的更专注的为大家提供关于“AI大模型全栈”的分享&#xff0c;特此以 AI 为关键元素更名账号名称&#xff0c;大家可以…

企业内网知识问答库小程序源码系统 收录好+排名高 带完整的安装代码包以及搭建部署教程

系统概述 企业内网知识问答库小程序源码系统是一款集知识收集、整理、检索与分享于一体的综合解决方案。它基于现代Web技术和小程序框架开发&#xff0c;旨在为企业内部员工提供一个便捷、高效的知识交流平台。该系统不仅支持文本、图片、视频等多种形式的内容输入&#xff0c…

国际版短剧系统开发,海外多语言切换短剧APP源码部署上架

一、背景与需求 1. 背景介绍 随着全球化进程的加速和移动互联网的普及&#xff0c;短剧作为一种新型娱乐形式在全球范围内迅速走红。海外短剧系统是针对这一市场需求而开发的&#xff0c;旨在为全球观众提供高质量的短剧内容&#xff0c;并通过多样化的平台和服务&#xff0c…

禁止吸烟监测系统 基于图像处理的吸烟检测系统 YOLOv7

吸烟是引发火灾的重要原因之一。烟头在未熄灭的情况下&#xff0c;其表面温度可达200℃-300℃&#xff0c;中心温度甚至能高达700℃-800℃。在易燃、易爆的生产环境中&#xff0c;如化工厂、加油站、仓库等&#xff0c;一个小小的烟头就可能引发灾难性的火灾&#xff0c;造成巨…

【前端样式】Sweetalert2简单用法

1、 先安装sweetalert2库&#xff1a; npm install sweetalert2 2、引用SweetAlert2 库&#xff1a; import Swal from sweetalert2 &#xff1b; 3、代码拷过去直接去测试&#xff0c;vue代码 <template><div><el-button style"color: #C03639" clic…

【计算机网络 - 基础问题】每日 3 题(二十八)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏&…

Kafka学习笔记(一)Linux环境基于Zookeeper搭建Kafka集群、Kafka的架构

文章目录 1 Kafka简介1.1 什么是Kafka1.2 Kafka的应用场景1.3 Kafka的优势 2 搭建Kafka集群2.1 搭建Zookeeper集群2.1.1 上传并解压安装包2.1.2 修改配置文件2.2.3 创建dataDir和myid文件2.2.4 分发到另外两个节点2.2.5 修改node-02节点、node-03节点的配置文件和myid文件2.2.6…

【原创教程】西门子_部件手动模式FB块编辑

1、软件配置 ①软件配置 名称 版本 博图 V16 2、建立FB块 在编辑手动程序前应该建立手动程序的FB块&#xff0c;FB块的建立内容如下图所示 ①FB块的输入接口 Input:FB块的输入接口&#xff0c;将下拉列表中的数据应用于该FB块所编辑的程序中。 NO&#xff1a;当前部件…

数据科学 - 字符文本处理

1. 字符串的基本操作 1.1 结构操作 1.1.1 拼接 • 字符串之间拼接 字符串之间的拼接使用进行字符串的拼接 a World b Hello print(b a) • 列表中的字符串拼接 将以分隔符‘,’为例子 str [apple,banana] print(,.join(str)); • 字符串中选择 通过索引进行切片操…