2.优化算法之滑动窗口1

1.长度最小的子数组

. - 力扣(LeetCode)

(1)题目描述 

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度如果不存在符合条件的子数组,返回 0 。

(2)原理

如何把暴力解法优化为滑动窗口 

解法一:暴力枚举出所有的子数组的和

解法二:滑动窗口-时间复杂度O(n)【暴力解法遇到单调性时】

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

2. 无重复字符的最长子串

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

(1)题目描述

子串的子数组都是连续的一串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长 

子串

 的长度。

示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。请注意,你的答案必须是 子串 的长度,"pwke"是一个子序列,不是子串。

(2)原理

解法一:暴力枚举 + 哈希表(判断字符是否重复出现) 

解法二:利用规律,使用滑动窗口

class Solution {public static int lengthOfLongestSubstring(String s) {int left=0,right=0,n=s.length();int len=0;if(n<=1){return n;}HashSet<Character> hashSet=new HashSet<>();for(left=0,right=0;right<n;right++){char exsitss=s.charAt(right);while(hashSet.contains(exsitss)){//出窗口hashSet.remove(s.charAt(left));left++;}//进窗口hashSet.add(exsitss);len=Math.max(len,right-left+1);}return len;}
}

 同时我们可以用数组模拟哈希表

3.最大连续1的个数3

1004. 最大连续1的个数 III - 力扣(LeetCode)

给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。

示例 1:

输入:nums = [1,1,1,0,0,0,1,1,1,1,0], K = 2
输出:6
解释:[1,1,1,0,0,1,1,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 6。

示例 2:

输入:nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], K = 3
输出:10
解释:[0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 10。

(1)题目描述

(2)原理

解法一:暴力枚举+zero计数器

解法二:滑动窗口

class Solution {public int longestOnes(int[] nums, int k) {int left=0,right=0,n=nums.length;int count=0;int lenlen=0;for(left=0,right=0;right<n;right++){//进窗口if(nums[right]==0){count++;}//出窗口while(count>k){if(nums[left]==0){count--;}left++;}lenlen=Math.max(lenlen,right-left+1);}return lenlen;}
}

 4.将x减到0的最小操作数

(1)题目描述

. - 力扣(LeetCode)

给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。

如果可以将 x 恰好 减到 0 ,返回 最小操作数 ;否则,返回 -1 。

示例 1:

输入:nums = [1,1,4,2,3], x = 5
输出:2
解释:最佳解决方案是移除后两个元素,将 x 减到 0 。

示例 2:

输入:nums = [5,6,7,8,9], x = 4
输出:-1

示例 3:

输入:nums = [3,2,20,1,1,3], x = 10
输出:5
解释:最佳解决方案是移除后三个元素和前两个元素(总共 5 次操作),将 x 减到 0 。

(2)原理

正难则反

 

class Solution {public int minOperations(int[] nums, int x) {//正难则反int left=0,right=0,n=nums.length;int sum=0;int sumsum=0;int len=Integer.MIN_VALUE;for(int i=0;i<n;i++){sum=sum+nums[i];}int target=sum-x;if(target==0){return n;}//滑动窗口for(left=0,right=0;right<n;right++){sumsum=sumsum+nums[right];while(sumsum>=target&&left<=right){if(sumsum==target){len=Math.max(len,right-left+1);}//出窗口sumsum=sumsum-nums[left];left++;}}return len==Integer.MIN_VALUE?-1:(n-len);}
}

 5.水果成篮

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

(1)题目描述

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

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

  • 你只有 两个 篮子,并且每个篮子只能装 单一类型 的水果。每个篮子能够装的水果总量没有限制。
  • 你可以选择任意一棵树开始采摘,你必须从 每棵 树(包括开始采摘的树)上 恰好摘一个水果 。采摘的水果应当符合篮子中的水果类型。每采摘一次,你将会向右移动到下一棵树,并继续采摘。
  • 一旦你走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘。

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

(2)原理

转化:找出一个最长的子数组的长度,子数组中不超过两种类型的水果

解法一:暴力枚举+哈希表

解法二:滑动窗口

class Solution {public int totalFruit(int[] fruits) {int n = fruits.length;Map<Integer, Integer> cnt = new HashMap<Integer, Integer>();int left = 0, ans = 0;for (int right = 0; right < n; ++right) {cnt.put(fruits[right], cnt.getOrDefault(fruits[right], 0) + 1);while (cnt.size() > 2) {cnt.put(fruits[left], cnt.get(fruits[left]) - 1);if (cnt.get(fruits[left]) == 0) {cnt.remove(fruits[left]);}++left;}ans = Math.max(ans, right - left + 1);}return ans;}
}

 Java HashMap getOrDefault() 方法 | 菜鸟教程 (runoob.com)

6.找出字符串所有字母异位词

(1)题目描述

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

给定两个字符串 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" 的变位词。

(2)原理

滑动窗口是固定的情况

class Solution {public List<Integer> findAnagrams(String ss, String pp) {List<Integer> ret=new ArrayList<>();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];if(++hash2[in-'a']<=hash1[in-'a']){//进窗口+维护,count为有效字符count++;}if(right-left+1>m){//出窗口,char out=s[left++];if(hash2[out-'a']--<=hash1[out-'a']){//出窗口+维护count--;}}//更新结果if(count==m){ret.add(left);}}return ret;}
}

 7.串联所有单词的子串

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

(1)题目描述

给定一个字符串 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"] 顺序排列的连接。

(2)原理

 

class Solution {public List<Integer> findSubstring(String s, String[] words) {List<Integer> ret=new ArrayList<>();Map<String,Integer> hash1=new HashMap<>();//保存字典中的所有字频for(String str:words){hash1.put(str,hash1.getOrDefault(str,0)+1);}int len=words[0].length(),m=words.length;//每个字符串长度是一致的for(int i=0;i<len;i++){//执行操作//滑动窗口的具体操作Map<String,Integer> hash2=new HashMap<>();//保存窗口中的所有字频for(int left=i,right=i,count=0;right+len<=s.length();right+=len){//进窗口+维护String in=s.substring(right,right+len);hash2.put(in,hash2.getOrDefault(in,0)+1);if(hash2.get(in)<=hash1.getOrDefault(in,0)){count++;}//出窗口if(right-left+1>len*m){//出窗口+维护String out=s.substring(left,left+len);if(hash2.get(out)<=hash1.getOrDefault(out,0)){count--;}hash2.put(out,hash2.get(out)-1);left+=len;}//更新结果if(count==m){ret.add(left);}}}return ret;}
}

 8.最小覆盖子串

(1)题目描述

给你一个字符串 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
  • s 和 t 由英文字母组成

(2)原理

合法的时候才出窗口

class Solution {public String minWindow(String ss, String tt) {char[] s=ss.toCharArray();char[] t=tt.toCharArray();int[] hash1=new int[128];//统计字符串t中字符的频次int kinds=0;//字符串t中,有多少种字符for(char ch:t){if(hash1[ch]++==0){kinds++;}}int[] hash2=new int[128];//统计滑动窗口字符的频次int minlen=Integer.MAX_VALUE,begin=-1;for(int left=0,right=0,count=0;right<s.length;right++){char in=s[right];if(++hash2[in]==hash1[in]){count++;//进窗口+维护count}while(kinds==count){//判断//更新结果if(right-left+1<minlen){begin=left;minlen=right-left+1;}char out=s[left++];if(hash2[out]--==hash1[out]){count--;//出窗口+维护count}}}if(begin==-1){return new String();}else{return ss.substring(begin,begin+minlen);}}
}

 

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

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

相关文章

计算机视觉——opencv快速入门(一) opencv的介绍与安装

什么是opencv OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和机器学习软件库。它旨在提供广泛的图像和视频处理功能&#xff0c;支持多种编程语言&#xff08;主要包括C, Python, Java等&#xff09;和操作系统&#xff08;如Li…

生产环境:CentOS 7 Docker 20.10.19离线部署(为离线部署k8s做准备)

背景描述&#xff1a;离线部署Docker环境 在现代IT基础设施中&#xff0c;Docker已经成为应用容器化的标准工具。它简化了应用程序的部署和管理&#xff0c;使开发者和运维工程师能够以更高的效率和一致性进行工作。然而&#xff0c;在某些场景下&#xff0c;由于安全性、网络…

代码随想录算法训练营第三十四天|56. 合并区间、738.单调递增的数字、968.监控二叉树

56. 合并区间 题目链接&#xff1a;56. 合并区间 文档讲解&#xff1a;代码随想录 状态&#xff1a;无语&#xff0c;这题从右边界排序做不了&#xff01; 思路&#xff1a; 排序&#xff1a;按照区间的起始位置进行排序&#xff0c;这样后面处理时可以顺序合并重叠区间。合并…

数据结构-线性表的链式表示

目录 前言一、线性表的链式表示和实现1.1 线性表的表示1.2 基本操作的实现1.3 线性表的链式表示的优缺点 总结 前言 本篇文章主要介绍线性表的链式表示 一、线性表的链式表示和实现 1.1 线性表的表示 线性表的链式表示又称为链式存储结构或链式映像 链式存储定义&#xff1…

emlogpro文件上传漏洞代码审计(CVE-2023-44974)(CVE-2023-44973)

【产品介绍】 emlog 是 “Every Memory Log” 的简称&#xff0c;意即&#xff1a;点滴记忆。它是一款基于PHP语言和MySQL数据库的开源、免费、功能强大的个人或多人联合撰写的博客系统(blog)。基于PHP和MySQL的功能强大的博客及CMS建站系统。致力于提供快速、稳定&#xff0c…

JAVA【案例5-2】模拟默认密码自动生成

【模拟默认密码自动生成】 1、案例描述 本案例要求编写一个程序&#xff0c;模拟默认密码的自动生成策略&#xff0c;手动输入用户名&#xff0c;根据用户名自动生成默认密码。在生成密码时&#xff0c;将用户名反转即为默认的密码。 2、案例目的 &#xff08;1&#xff09…

JavaWeb系列六: 动态WEB开发核心(Servlet) 上

韩老师学生 官网文档为什么会出现Servlet什么是ServletServlet在JavaWeb项目位置Servlet基本使用Servlet开发方式说明快速入门- 手动开发 servlet浏览器请求Servlet UML分析Servlet生命周期GET和POST请求分发处理通过继承HttpServlet开发ServletIDEA配置ServletServlet注意事项…

【Python/Pytorch - 网络模型】-- 高阶SVD算法

文章目录 文章目录 00 写在前面01 基于Python版本的高阶SVD算代码02 HOSVD 的步骤 00 写在前面 高阶奇异值分解&#xff08;Higher-Order SVD&#xff0c;HOSVD&#xff09;是一种将传统的奇异值分解&#xff08;SVD&#xff09;扩展到高阶张量的方法。它能够将一个高阶张量分…

【AI编译器】triton学习:矩阵乘优化

Matrix Multiplication 主要内容&#xff1a; 块级矩阵乘法 多维指针算术 重新编排程序以提升L2缓存命 自动性能调整 Motivations 矩阵乘法是当今高性能计算系统的一个关键组件&#xff0c;在大多数情况下被用于构建硬件。由于该操作特别复杂&#xff0c;因此通常由软件提…

mprpc框架的配置文件加载

目录 1.回顾测试 2.mprpc框架的配置文件加载 2.1 mprpcconfig.h 2.2 完善mprpcapplication.h 2.3 完善mprpcapplication.cc 2.4 mprpcconfig.cc 2.5 test.conf 2.6 测试运行 ​3.扩展问题 1.回顾测试 我们先把之前的项目代码工程编译好&#xff0c;然后进入bin里面&am…

GPOPS-II教程(2): 可复用火箭再入大气层最优轨迹规划问题

问题描述 考虑一类可复用火箭再入大气层最优轨迹规划问题&#xff0c;其动力学方程为 { r ˙ v sin ⁡ γ , θ ˙ v cos ⁡ γ sin ⁡ ψ r cos ⁡ ϕ , ϕ ˙ v cos ⁡ γ cos ⁡ ψ r , v ˙ − F d m − F g sin ⁡ γ , γ ˙ F l cos ⁡ σ m v − ( F g v − v r …

高考填报志愿(选专业),为什么要尊重孩子的选择 ?

没有哪一位父母不希望自己的孩子能够考到理想的大学&#xff0c;甚至光宗耀祖&#xff0c;然而一些比较专制的家长&#xff0c;往往在孩子填报志愿的时候表现出很强的控制欲&#xff0c;希望将自己的意愿强加于孩子身上&#xff0c;并没有考虑到他们的兴趣是什么。其实&#xf…

【IM 服务】新用户为什么刚注册就能收到通知?为什么能接收注册前的通知?

功能说明&#xff1a; 默认新注册的用户可以接收到注册前 7 天内的广播消息。您可以从控制台免费基础功能页面关闭该服务。 开通方式&#xff1a; 访问开发者后台 免费基础功能 1页面&#xff0c;确认应用名称与环境&#xff08;开发 /生产 &#xff09;正确无误后&#xff0c…

springboot+vue+mybatis门窗管理系统+PPT+论文+讲解+售后

如今社会上各行各业&#xff0c;都在用属于自己专用的软件来进行工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。互联网的发展&#xff0c;离不开一些新的技术&#xff0c;而新技术的产生往往是为了解决现有问题而产生的。针对于仓库信息管理方…

Java-day01--基础知识

1、计算机基础知识&#xff1a; 计算机主要是由硬件和软件组成&#xff0c;软件指的是特定顺序的计算机指令&#xff0c;硬件主要可以看成是系统软件和应用软件等。 目前java主流分成三种&#xff1a;javase&#xff08;标准版&#xff09;、javame&#xff08;小型版&#x…

优化了自制的浏览器主页的全屏功能

第一次修改 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>全屏功能</title><style>…

数据分析必备:一步步教你如何用matplotlib做数据可视化(12)

1、Matplotlib 3D线框图 线框图采用值网格并将其投影到指定的三维表面上&#xff0c;并且可以使得到的三维形式非常容易可视化。plot_wireframe()函数用于此目的 import matplotlib.pyplot as plt import numpy as np import math import seaborn as sns plt.rcParams[font.s…

数据结构-----【链表:基础】

链表基础 1、链表的理论基础 1&#xff09;基础&#xff1a; 链表&#xff1a;通过指针串联在一起的线性结构&#xff0c;每个节点由两部分组成&#xff0c;一个是数据域&#xff0c;一个是指针域&#xff08;存放指向下一个节点的指针&#xff09;&#xff0c;最后一个指针…

在flask中加载mnist模型,并预测图片

一、在tensorflow中新建及保存模型 启动Jupyter Notebook 新建Notebook 生成 mnist_model.h5 模型的代码 import tensorflow as tf from tensorflow.keras.datasets import mnist from tensorflow.keras.models import Sequential from tensorflow.keras.layers import…

机器人控制系列教程之运动规划(2)

简介 在笛卡尔坐标空间中轨迹规划时&#xff0c;首先用位置矢量和旋转矩阵表示所有相应的机器人节点&#xff0c;其次在所有路径段插值计算相对的位置矢量和旋转矩阵&#xff0c;依次得出笛卡尔坐标空间中的轨迹序列通过求解运动学逆问题得到相应关节位置参数。 优点&#xf…