【优选算法】滑动窗口算法:专题一

【优选算法】滑动窗口算法:专题一

目录

引言:

 【209. 长度最小的子数组】

题目描述:

实现核心及思路:

思路可视化:

代码实现:

【无重复字符的最长子串】

题目描述:

实现核心及思路:

思路可视化:

代码实现:

【最大连续1的个数III】

题目描述:

实现核心及思路:

代码实现:

【1658.将x减到0的最小操作数】

题目描述:

实现核心即思路:

代码实现:


引言:

滑动窗口?用两个指针维护一个动态的 “窗口” 区间,通过移动指针来扩大或缩小窗口,在一次遍历中完成计算,时间复杂度通常为 O (n)。

典型应用:寻找最长无重复字符的子串找到和为目标值的最短子数组字符串的排列匹配
一般步骤(模板):

(1)定义left 和 right 指针同时指向数组首元素;

(2)当符合要求时,right++,模拟进窗口;

(3)不满足要求时,left++,模拟出窗口;

(4)并根据具体情况更新结果。

结束条件:当right 越界。

具体我们通过下面的题目来深入认识它!!!

 【209. 长度最小的子数组

题目描述:

实现核心及思路:

由于数组元素均为正整数,所以当求和时满足单调性,套用上面的模板:

(1)定义left 和 right 指针,同时指向首元素;

(2)right 指针向右移动,进窗口,并求和 sum;当和 大于或等于target 时,更新结果;

(3)left指针向右移动,出窗口,同时让 sum 减去nums[left],直到sum小于target。

注意:在出窗口时,如果满足sum >= target,也要更新结果。
思路可视化:
代码实现:
class Solution { public: int minSubArrayLen(int target, vector<int>& nums) { int left = 0, right = 0; int len = INT_MAX, sum = 0; while(right < nums.size()) { sum += nums[right]; // 求和 while(sum >= target) // 保证窗口合法 { len = min(len, right - left + 1); // 更新结果 sum -= nums[left++]; // 出窗口 } right++; // 继续进窗口 } return len == INT_MAX ? 0 : len; } };

【无重复字符的最长子串】

题目描述:

实现核心及思路:

找不含重复字符的最长子串,我们需要一个标记来判断字符是否重复。ASCII总共有127个字符, 所以我们用一个大小为128的数组模拟哈希表,当一个字符进窗口就数组中与其映射位置上的元素++,只要值大于1就说明重复

(1)定义left 和 right 指针,同时指向字符串开头;

(2)right 指针向右移动,进窗口,哈希表对应位置元素++,满足要求则更新结果;

(3)出现重复字符,left 指针向右移动,直到找到重复字符,然后继续让 right++;

注意:left向右移动过程中(出窗口),哈希表对应位置的元素要 --,因为这些字符已经不在窗口中了。
思路可视化:
代码实现:
class Solution { public: int lengthOfLongestSubstring(string s) { int hash[128] = {0}; int left = 0, right = 0,size = s.size(), len = 0; while(right < size) { hash[s[right]]++; // 标记 // 重复 if(hash[s[right]] > 1) { // 找重复字符,保证窗口合法(出窗口) while(s[left] != s[right]) { hash[s[left]]--; // 去掉标记 left++; } // 重复字符出窗口 hash[s[left]]--; left++; } w = max(w, right - left + 1); // 更新结果 right++; // 继续进窗口 } return w; } };

【最大连续1的个数III】

题目描述:

实现核心及思路:

相比上面找最长无重复的子串,此题就是在此基础上可以掺杂 k 个0,所以我们要控制窗口中0的个数,始终维护一个合法有效的窗口。

(1)定义left 和 right 指针,同时指向字符串开头;定义 cnt 记录0的个数(用来维护窗口合法);

(2)right 指针向右移动,进窗口:

  • 如果nums[right] 等于1则right++,并更新结果;
  • 如果等于0,则cnt++:如果cnt <= k,说明窗口合法,right++,并更新结果;如果cnt > k,则要多余的0出窗口,即让left++,直到找到0,让cnt--,使得cnt == k。
优化:最长子串其实在窗口中的0的个数等于k + 1时,所以,我们只需要在cnt > k时更新结果。但这样做,还需要在最后再更新一下结果,防止遍历完整个数组cnt 还是小于等于k

代码实现:

class Solution { public: int longestOnes(vector<int>& nums, int k) { int left = 0, right = 0; // 左右指针,维护窗口 int size = nums.size(); int result = 0, cnt = 0; // 记录结果和当前遍历到的0的个数 while(right < size) { if(nums[right] == 0) { cnt++; // 0 个数更新 if(cnt > k) // 0个数不满足k { result = max(result, right - left); // 更新结果 // 左边的元素出窗口,直到0的个数重新满足要求 while(cnt > k) { if(nums[left] == 0) { cnt--; // 0个数-- } left++; } } } right++; } result = max(result, right - left); // 再次更新结果 return result; } };

【1658.将x减到0的最小操作数】

题目描述:

实现核心即思路:

直接上手,其实非常麻烦,因为我们完全不知道该从左边找还是右边找,能够让x恰好被减到0。所以我们对这个问题进行转化:

假设从左边和右边找到了几个连续的元素,求和为x,则此时x可以被减到0。设数组所有元素之和为sum,又有sum1 + sum3 = x,则sum2 = sum - x。

我们只要在中间找到一个连续的和为sum - x的最长的子数组,就能找到最少的次数了

又因为所有数组元素都大于0,则求和满足单调性,所以就能用滑动窗口来解决了。

(1)预处理:求数组所有元素之和sum,目标值 val = sum - x;

(2)left 和 right 指针维护窗口,add记录窗口中元素之和,len记录中间子数组长度;

细节:将len初始化为 -1,如果没找到满足的子数组,不会更新len的值,返回-1。 

(3)right++,向右移动进窗口,add += nums[right]:

  • 当 add < val,right继续向右移动,进窗口;
  • 当 add > val,由于单调性,left++,出窗口,add -= nums[left],循环,直到add <= val,即当窗口合法;
  • 当 add == val,更新len,记录len的最大值。
结束条件:right 越界。

(4)返回结果,nums.size() - len。

代码实现:

class Solution { public: int minOperations(vector<int>& nums, int x) { // 预处理:求和 int sum = 0; for(auto e:nums) sum += e; int left = 0, right = 0; // 左右窗口 // 转化为中间找一个和为sum - x的子数组 int val = sum - x; // 处理特殊情况 if(val < 0) return -1; int add = 0, len = -1; // 记录子数组和与长度 while(right < nums.size()) { add += nums[right++]; // 进窗口 while(add > val) { add -= nums[left++]; // 出窗口 } if(add == val) { len = max(len, right - left); // 更新结果 } } if(len == -1) return -1; else return nums.size() - len; } };

Read more

具身智能与视觉:机器人如何“看懂”世界?

具身智能与视觉:机器人如何“看懂”世界?

具身智能与视觉:机器人如何“看懂”世界? * 前言 * 一、具身智能的奥秘探索 * 1.1 具身智能的深度剖析 * 1.2 具身智能的发展脉络梳理 * 二、视觉:机器人感知世界的 “慧眼” * 2.1 机器人视觉系统的架构解析 * 2.2 计算机视觉技术的关键支撑 * 三、机器人如何借助视觉 “看懂” 世界 * 3.1 视觉感知与环境理解 * 3.2 视觉引导下的决策与行动 * 3.3 视觉与其他传感器的融合 * 四、具身智能中视觉技术的挑战 * 4.1 复杂环境下的视觉鲁棒性 * 4.2 实时性与计算资源的平衡 * 4.3 语义理解与常识推理的欠缺 * 五、具身智能视觉技术的未来发展趋势 * 5.

By Ne0inhk

FPGA摄像头采集处理显示完全指南:从OV5640到HDMI实时显示(附完整工程代码)

FPGA摄像头采集处理显示完全指南:从OV5640到HDMI实时显示(附完整工程代码) 📚 目录导航 文章目录 * FPGA摄像头采集处理显示完全指南:从OV5640到HDMI实时显示(附完整工程代码) * 📚 目录导航 * 概述 * 一、摄像头采集处理显示系统概述 * 1.1 系统架构与核心模块 * 1.1.1 完整系统架构 * 1.1.2 核心模块功能说明 * 1.1.3 数据流向 * 1.2 应用场景与实现方案 * 1.2.1 典型应用场景 * 1.2.2 不同分辨率的实现方案 * 1.3 设计流程与关键技术点 * 1.3.1 设计流程 * 1.3.2 关键技术点 * 1.

By Ne0inhk
【花雕学编程】Arduino BLDC 之模糊逻辑避障控制机器人

【花雕学编程】Arduino BLDC 之模糊逻辑避障控制机器人

基于 Arduino 的无刷直流电机(BLDC)模糊逻辑避障控制机器人,是将智能控制理论与高效动力系统相结合的典范。它摒弃了传统避障算法中对精确数学模型的依赖,转而模拟人类的经验决策过程,使机器人在复杂、不确定的环境中表现出更强的适应性和鲁棒性。 1、主要特点 基于模糊逻辑的智能决策机制 模糊逻辑控制(FLC)的核心在于处理“不确定性”和“模糊性”,这使其在动态避障中具有天然优势。 突破二值逻辑: 传统控制基于“是/否”、“0/1”的二值逻辑,而模糊逻辑引入了“隶属度函数”,允许变量处于“部分真”的状态。例如,距离不再是具体的“30cm”,而是“较近”、“适中”或“较远”的模糊概念。这种描述方式更贴近人类处理环境信息的方式。 仿人经验控制: 系统通过预设的“If-Then”规则库(如“如果前方距离很近,且左侧距离较远,则向左急转”

By Ne0inhk
介绍终身机器人学习的数据集LIBERO

介绍终身机器人学习的数据集LIBERO

1 LIBERO的作用 LIBERO是一个用于研究多任务和终身机器人学习中知识迁移的综合基准测试平台,LIBERO是基于robosuite框架构建的。它专注于机器人操作任务,这些任务需要两类知识: 1. 陈述性知识:关于物体和空间关系的知识 2. 程序性知识:关于运动和行为的知识 2 核心原理 任务生成与基准设计 LIBERO提供了一个程序化生成管道,原则上可以生成无限数量的操作任务。系统包含130个任务,分为四个任务套件,每个套件都有受控的分布偏移: * LIBERO-Spatial/Object/Goal:专注于特定类型知识的迁移 * LIBERO-100:包含需要迁移纠缠知识的100个操作任务 学习框架 系统采用模仿学习作为主要学习方法,因为任务使用稀疏奖励函数(任务完成时获得+1奖励)。LIBERO提供高质量的人类遥操作演示数据集用于训练。 算法与策略架构 LIBERO实现了三种视觉运动策略网络: * bc_rnn_policy:基于RNN的行为克隆策略 * bc_transformer_policy:基于Transformer的行为克隆策略

By Ne0inhk