Java滑动窗口算法核心:题型识别、实现细节与高频题实战

滑动窗口这四个字,在Java算法面试里的出现频率,比我写过的任何设计模式都高。用Java写题的开发者,看到“连续子数组”“子串”这类描述,脑子里就应该立刻蹦出这套打法。既然标题叫“滑动窗口 2”,我默认你已经见过基础的双指针滑动写法,所以这篇会直接聊更关键的东西:窗口收缩的时机怎么判断、Java代码里到底有哪些容易出问题的细节、四道高频题怎么一步步写出来、以及我踩过的调试坑。如果你连滑动窗口是什么都还没摸清,从这篇开始也没问题,我会把原理部分讲得足够直白。滑动窗口解决的核心问题,是在一段线性数据上寻找满足某个约束的连续区间,暴力两重循环能出结果,但面试和实际数据处理都不会满意,窗口打法把它压成一次遍历,这就是它最大的价值。

1. 滑动窗口为什么值得单开一篇:先搞懂它快在哪

1.1 窗口的本质是“带状态的连续区间”

滑动窗口说白了就是:左指针和右指针圈出一个连续区间,右指针负责扩张、左指针负责收缩,区间在遍历过程中像条毛毛虫一样往前爬。但真正让它高效的不是“双指针”这个外壳,而是“状态持续维护”这个内核。

很多人写暴力解法为什么会慢?因为每次枚举一个新的起点,都要重新计算一遍这个起点到终点的所有信息。比如求“无重复字符的最长子串”,暴力写法里每移动一个起点,就要重新扫描到末尾看看哪里开始重复,重复扫描的次数多了,复杂度自然变成O(n²)。而滑动窗口的做法是,手里始终维护一个窗口的完整记录,右指针往前走一步,我往记录里加一个新字符;左指针往前走一步,我从记录里删掉一个旧字符。每次只做常数级的增量更新,而不是全量重算。

我用一个生活化类比来解释:你站在一条传送带前检查连续产品的合格区间,暴力做法是每移动一个位置就把前面所有产品重新数一遍;滑动窗口的做法是,手里永远只维护一箱产品的台账,传送带往前送一个,你从台账里加一个新品、去掉一个旧品,随时知道当前箱子里什么情况。整个流水线走完,你也只是每个产品进出一次台账,工作量线性增长。

1.2 时间复杂度的数学直觉

滑动窗口的时间复杂度是O(n),这个结论很多面试的人都会背,但被追问“为什么内层还有一个while循环,复杂度不是O(n²)吗”就卡住了。其实道理很简单:right指针从0走到n-1,每一步都可能触发left指针的收缩,但left指针总共也只能从0走到n-1。也就是说,整个算法过程中,left指针移动的总次数不会超过n,right指针移动的总次数也不会超过n,加在一起最多2n次操作。内层那个while无论执行多少次,它消耗的都是left指针的总移动额度,而不是每次外层循环都重新移动n次,所以均摊下来依然是O(n)。

这个分析方式是面试加分项。很多人只会写代码,讲不清楚复杂度怎么来的,而面试官恰恰喜欢在这个点深挖。你如果把“每个元素最多被right加入一次、被left移出一次”这句话说出来,在面试官眼里就和背模板的选手拉开了差距。

1.3 识别滑动窗口题型的三个信号

刷题多了你会发现,滑动窗口不是万能的,但它有非常明显的适用特征。我总结成三个信号,同时看到三个基本就可以往窗口上想。

第一个信号,题目要求的是连续子数组或子串,而不是子序列。子序列允许跳着选,窗口是管不了的,窗口只能处理原始顺序中连成一体的区间。第二个信号,题目里出现了“最长”“最短”“包含”“覆盖”“至少”“不超过”这类对区间整体性质的限定,而且这个性质随区间扩大或缩小是单调变化的。什么叫单调?窗口越大,和越大;窗口越大,越容易出现重复字符;窗口越大,越容易覆盖目标字符集。这种单向变化的趋势,正是left指针可以放心收缩的依据。第三个信号,数据规模提示你需要O(n)解法,通常在几万到几十万这个量级,O(n²)基本要超时。

反过来也要会排除。如果题目要求的是“子序列的某种最优值”,窗口直接失效;如果要求窗口内元素满足非单调的组合条件,比如“窗口内元素互质”之类,left收缩的判断依据不成立,滑动窗口也无能为力。我见过不少人拿到题就套窗口模板,最后套不进去还怀疑自己写错了,其实是题型判断就偏了。

题目特征是否适合滑动窗口
连续子数组/子串,求最大最小值适合
子序列,允许跳选不适合
窗口扩大时约束单向变化适合
约束不具备单调性不适合
数据量在10^5左右适合,窗口O(n)通过

2. Java实现滑动窗口的3个关键细节:指针节奏、统计结构与状态设计

2.1 左右指针的移动节奏:先加右还是先缩左

Java写窗口题,骨架就一句话:外层while控制右指针扩张,内层while控制左指针收缩。但很多人折在“更新答案的位置”上。这里没有一劳永逸的公式,关键在于想清楚:你手里的窗口在哪个时刻是“候选答案”。

拿“无重复字符的最长子串”举例,右指针把一个新字符加进来之后,窗口可能已经出现重复,必须先收缩到合法,此时的窗口长度right - left才是有效的候选值,所以在收缩之后更新答案。而“长度最小的子数组”这类题,右指针加数之后窗口和变大,满足条件后开始收缩,收缩过程的每一步都可能出现更短的合法窗口,所以答案要在收缩过程中持续更新。再比如“最小覆盖子串”,收缩到刚好不满足条件的前一步,那个窗口才是当前右边界下的最优解。

我把这三类情况拆开讲透,就是下面这个小节的内容。但先记住一个朴素原则:往窗口里加元素时,只加右指针指向的元素;从窗口移除元素时,只移左指针指向的元素。顺序永远是“先改状态,再移动指针”,这两步的顺序一旦写反,窗口状态和指针位置就对不上,调试时特别难发现。

2.2 频次统计用HashMap还是int数组:性能与坑的取舍

窗口题最常见的状态就是“某个字符/数字出现了几次”。Java里两条路:HashMap<Character, Integer>,或者int[128]/int[256]数组。我的习惯很明确:只要输入是ASCII字符范围,一律用int数组;只有值域不可控的大整数场景,才用HashMap。

int数组的好处不只是快。它避免了Integer装箱拆箱的开销,也躲开了一个经典坑:HashMap的get方法在键不存在时返回null,而null参与加减运算直接抛NullPointerException。用getOrDefault可以规避,但每次写起来都得多打几个字符。还有一个更隐蔽的坑:Integer有缓存区间,-128到127之间的Integer对象用==比较可能“碰巧”相等,超出这个范围就出错。如果你用map的value做频次判断,等值比较一定不要用==。用int数组,下标就是字符本身,值就是int,完全没有这些心智负担。

提示:字符统计用int[128]覆盖ASCII、int[256]覆盖扩展ASCII;如果是小写字母题,int[26]更省,记得减'a'。

如果是数字题且值域可控,比如题目告诉你数组元素不超过某个最大值,直接开对应长度的数组;如果值域很大又稀疏,HashMap是合理选择,但建议对value做intValue()处理,避免自动拆箱带来的潜在问题。

2.3 窗口状态设计:把“数量”和“种类”分开维护

窗口题翻车,大多不是指针移动错,而是窗口内“状态”没设计对。最典型的是最小覆盖子串这类题:既要统计每个字符在窗口里出现了几次,又要判断当前窗口是否覆盖了目标串的所有字符。这里有两个概念必须分开:目标串某个字符需要多少个,以及一共有多少种字符还没被满足。

举例,目标串是“AAB”,那么字符A需要2个、字符B需要1个,但“还有几种字符没满足”这个值是2,因为A和B都是缺的。如果你用一个计数器统计总缺失个数,A缺2个、B缺1个加起来是3,这个值在窗口加入一个A后会变成2,看起来好像“满足程度”提升了,但实际A这种字符依然缺1个,缺失种类数还是2。所以正确做法是:用一个need数组记录每个字符还缺多少,用一个missing变量记录“还有多少种字符没补齐”。need数组的增减在每次加字符、移字符时同步更新,但missing只在某个字符的need从正数变为0(补齐)或从0变为正数(重新变缺)时才变化。

这个设计不是死记硬背的模板,而是从问题语义里自然推导出来的。你写窗口题时,可以先问自己一句:我需要在窗口里追踪哪些独立维度?是频次、是和、是乘积,还是“哪些条件满足了”?把维度列清楚,代码结构自然就清晰了。

3. 四道高频滑动窗口题实战拆解:从无重复子串到固定窗口

3.1 无重复字符的最长子串:把可变窗口玩明白

题目要求给定字符串s,找出其中不含重复字符的最长子串长度。这题是可变窗口的入门题,也是我建议所有人都能徒手写出来的题。

public int lengthOfLongestSubstring(String s) { int n = s.length(); int[] freq = new int[128]; int left = 0, right = 0; int ans = 0; while (right < n) { char c = s.charAt(right); freq[c]++; right++; while (freq[c] > 1) { char d = s.charAt(left); freq[d]--; left++; } ans = Math.max(ans, right - left); } return ans; }

这段代码最巧妙的地方在于:判断是否需要收缩时,只检查刚加入的字符c的频次。为什么可以只检查它?因为在加入c之前,窗口已经是合法窗口,没有任何重复字符;加入c之后,唯一可能让窗口变违法的就是c自己出现了第二次。所以只要freq[c] > 1,说明c重复了,此时收缩左边界,把左指针指向的字符一个一个移出去,直到c的频次回到1,窗口再次合法。这个“破坏条件的一定是新元素”的局部性思维,是很多窗口题的快速判断依据。

答案在收缩后更新,因为right - left此时对应的正是一个合法且可能最长的窗口。空串的情况天然被覆盖,因为外层while不会进入,ans保持0。

3.2 最小覆盖子串:窗口里的计数与缺失标记

题目给两个字符串s和t,在s中找到包含t所有字符(含重复字符)的最短连续子串,没有则返回空串。这题比上一题难一个档次,也是面试里区分“会写模板”和“真懂窗口”的经典题。

public String minWindow(String s, String t) { int[] need = new int[128]; for (char c : t.toCharArray()) need[c]++; int missing = 0; for (int v : need) { if (v > 0) missing++; } int left = 0, right = 0; int minLen = Integer.MAX_VALUE; int start = 0; int n = s.length(); while (right < n) { char c = s.charAt(right); need[c]--; if (need[c] == 0) missing--; right++; while (missing == 0) { if (right - left < minLen) { minLen = right - left; start = left; } char d = s.charAt(left); if (need[d] == 0) missing++; need[d]++; left++; } } return minLen == Integer.MAX_VALUE ? "" : s.substring(start, start + minLen); }

这里need数组的含义是“这个字符还缺多少个”,初始值是t的需求量。右指针加入字符c时,need[c]减一;如果need[c]恰好从1变成0,说明这个字符种类的缺口被补齐,missing减一。注意如果need[c]减成负数,说明窗口里这个字符已经盈余了,missing不要动,因为该字符的种类已经满足了。

收缩时的判断是对称的。左指针移出字符d之前,先看need[d]是否为0:如果为0,说明d刚好够用,移除它之后缺一个,所以missing加一;然后need[d]加一。判断时机必须在need[d]变化之前,写完再看一眼顺序就明白了。收缩过程中每移动一次left就更新一次答案,因为每一次移动都可能让窗口变成“新的合法且更短”的状态。

3.3 长度最小的子数组:简单题反而最容易错答案位置

题目给一个正整数数组nums和一个正整数target,找出满足和大于等于target的长度最小的连续子数组并返回长度。这题看着简单,但我在实际辅导里发现错误率不低,原因就是答案更新位置。

public int minSubArrayLen(int target, int[] nums) { int left = 0, sum = 0; int ans = Integer.MAX_VALUE; for (int right = 0; right < nums.length; right++) { sum += nums[right]; while (sum >= target) { ans = Math.min(ans, right - left + 1); sum -= nums[left]; left++; } } return ans == Integer.MAX_VALUE ? 0 : ans; }

答案更新写在while循环开头,先记录当前合法窗口长度,再收缩。如果把更新写在收缩完成之后,记录的很可能是已经不满足条件的窗口长度,答案就会偏大。为什么这题要在收缩过程中更新,而“无重复字符的最长子串”要在收缩后更新?因为前者收缩的每一步都可能得到更短合法窗口;后者收缩只是为了排除重复,排除完成后窗口才是合法的。

这道题还有一个隐藏前提:数组必须是正整数。因为正整数保证了sum随窗口扩大单调递增,left收缩的时机才有据可依。如果数组里有负数,sum不再单调,窗口收缩的判断就失效了,这题得用前缀和加其他方案。

3.4 字符串排列匹配:固定窗口的滑动技巧

题目给两个字符串s1和s2,判断s2是否包含s1的某个排列。翻译成人话就是:s2中是否存在一个长度等于s1的连续子串,它的字符频次和s1完全一样。

这题是固定窗口的典型。窗口长度固定为s1的长度,每次移动相当于右边进来一个新字符、左边出去一个旧字符,然后比较当前窗口的频次是否与s1一致。直接比较两个HashMap也能过,但每次都要全量比较一遍,时间常数大。更好的方案是维护差分计数和一个diff变量,记录两个频次数组有多少个位置的差异,移动窗口时只局部更新diff。

public boolean checkInclusion(String s1, String s2) { int n = s1.length(), m = s2.length(); if (n > m) return false; int[] cnt = new int[26]; for (int i = 0; i < n; i++) { cnt[s1.charAt(i) - 'a']++; cnt[s2.charAt(i) - 'a']--; } int diff = 0; for (int v : cnt) { if (v != 0) diff++; } if (diff == 0) return true; for (int i = n; i < m; i++) { int add = s2.charAt(i) - 'a'; int rem = s2.charAt(i - n) - 'a'; if (cnt[add] == 0) diff++; cnt[add]--; if (cnt[add] == 0) diff--; if (cnt[rem] == 0) diff++; cnt[rem]++; if (cnt[rem] == 0) diff--; if (diff == 0) return true; } return false; }

diff的维护逻辑是:某位置从0变成非0,说明多了一处差异,diff加一;从非0变成0,说明差异消失,diff减一。每次更新一个字符时,先记录旧值是否为0,再做频次修改,再检查新值是否为0。顺序错了,diff就会统计错误。这个局部更新思路不仅适用于这题,遇到任何“判断两个窗口内容是否相等”的场景都可以套用。

3.5 一个可以直接套用的Java通用模板

综合上面几道题,我沉淀出一个固定骨架。写新题时,你只需要替换“状态更新”和“收缩判断”两处。

int left = 0, right = 0; // 状态:频次数组、计数变量、sum等 while (right < n) { // 1. 加入右边元素,更新状态 // 2. 当窗口违反约束时,收缩左边界 while (需要收缩) { // 可选:在此处更新答案,适合“求最短/最小”类 // 移除左边元素,更新状态 left++; } // 3. 窗口已经合法,更新答案,适合“求最长/最大”类 right++; }

记住两条经验:求最短/最小,答案常在收缩过程中更新;求最长/最大,答案常在收缩完成后更新。但这不是铁律,关键还是要回到题目语义里确认,你用来更新答案的窗口在当时是否满足问题条件。

4. 滑动窗口常见Bug排查与调试心得:现场实录

4.1 死循环:left和right的推进顺序写反了

我见过最多的bug,就是内层while收缩时忘了在循环体最后让left自增,导致同一个字符被反复移除,程序卡死。另一个常见问题是right的自增写在状态更新之前,指针已经移动了,窗口状态却没跟上,后续判断全部错乱。

我的排查习惯是:先检查“先改状态,再移动指针”这个顺序。右指针扩张时,一定是先根据当前right指向的元素更新状态,再right++;左指针收缩时,一定是先根据当前left指向的元素更新状态,再left++。如果反过来了,窗口的边界和内容就对不上,轻则结果错误,重则死循环。

4.2 Integer缓存与自动拆箱:HashMap统计频次的隐形坑

用HashMap<Character, Integer>做窗口统计时,有一个藏得很深的坑:Integer对象有缓存区间,==比较在-128到127之间可能返回true,超出范围返回false。如果你在窗口题里用==比较两个频次是否相等,小范围测试数据能过,换大范围数据就莫名其妙出错。频次比较一律用intValue()或者直接操作int。

另一个是空指针。window.get(c)在键不存在时返回null,直接做加减运算会抛NullPointerException。正确写法是getOrDefault(c, 0)。我见过太多初学Java的人在这里栽跟头,而且报错信息在力扣上往往被截断,不好定位。用int[128]之后,这类问题直接消失,这也是我强烈建议字符统计用数组的原因。

4.3 日志调试法:把窗口内容打印出来看

遇到窗口题逻辑不对,我从来不一上来就断点debug。先打日志,打印每次迭代前后的left、right和窗口内容。对于字符串题,可以直接打印s.substring(left, right),一眼就能看到当前窗口到底是什么。

调试代码长这样:左指针、右指针、频次数组、窗口文本,四个信息打在一行。跑一遍小数据,比如“abcabcbb”,观察每行输出的窗口文本变化,很快就能看出左指针是否在正确时机收缩、窗口是否在正确范围滑动。调试完记得把打印语句删掉,或者用日志开关控制,不然提交的时候输出一堆调试信息,结果页面上全是日志,我自己就犯过这毛病。

4.4 验证复杂度的实操方法

写完窗口代码,我会用三种数据自测。第一,题目给的示例,验证基本逻辑;第二,构造最坏情况,比如全是相同字符的超长字符串,确保left指针持续收缩但不卡死;第三,构造百万级随机数据,体感一下运行时间是否接近线性。

如果想更严谨,可以在代码里加一个计数器,统计内层while的总执行次数。跑完后如果发现总次数约等于n,说明每个元素平均被移出一次,复杂度没问题;如果总次数远超n,说明收缩逻辑有重复消耗,肯定有bug。

注意:不要只在示例数据上验证就提交。窗口题最容易栽在空输入、全同字符、目标串长度大于主串这类边界上,提前构造好测试用例能省大量提交时间。

4.5 为什么有的题先更新答案、有的题后更新:一次讲清楚

我辅导过不少人,对“答案更新位置”始终模糊。这里给一个对比矩阵,你对照着看就清楚了。

题目类型更新时机原因
无重复字符的最长子串收缩完成后更新窗口收缩后才恢复合法,此时长度才是候选答案
长度最小的子数组收缩过程中更新收缩的每一步都可能产生更短的合法窗口
最小覆盖子串收缩过程中更新收缩到不满足条件的前一步,窗口刚好合法且最短
字符串排列匹配固定窗口,每次移动后判断窗口长度固定,移动后立即判断即可

说到底,答案更新位置不是背出来的,而是由“哪个时刻的窗口满足题目要求”决定的。你每次写窗口题,先问自己这个问题,答案位置自然就对了。

4.6 我的几个实操习惯

最后分享几个我写窗口题一直用的习惯。第一,动手写代码前,先在一张草稿纸上画出窗口移动的瞬间状态,标出left和right的位置以及窗口内容的变化。尤其是可变窗口,纸面上能看出左指针什么时候动、右指针什么时候停,比直接敲代码清晰得多。第二,每写完一段状态更新,立刻用一句话描述它的语义,比如“这句的意思是:把字符c加入窗口,频次加一”。如果描述不出来,说明状态设计有问题。第三,把经典题反复手写,直到不依赖模板也能在几分钟内在纸上写出核心逻辑。手写和看代码完全是两回事,尤其是指针移动和状态更新的耦合关系,只有亲手写几遍才能真正建立肌肉记忆。

我个人在实际操作中体会到,滑动窗口这套打法之所以在Java算法题里高频出现,不只是因为它能帮忙应付面试,更因为它是一种通用的区间优化思维:任何需要在连续数据上维护动态范围信息的场景,都可以先想想“能不能用窗口把全量重算变成增量更新”。这个思路迁移到日志分析、流数据处理、实时统计这类工程问题里,照样能派上用场。窗口不大,但把它吃透,收益远比会背几道题大得多。

相关新闻

MATLAB疑难杂症诊疗手册:从报错定位到性能调优的完整指南

MATLAB疑难杂症诊疗手册:从报错定位到性能调优的完整指南

先把话说在前头——MATLAB疑难杂症诊疗这个题目&#xff0c;拆开来看就是两件事&#xff1a;一是那些让人抓狂的报错&#xff0c;二是报错背后真正的原因。我见过太多人对着满屏红色代码干瞪眼&#xff0c;第一反应是“重新装一遍MATLAB”&#xff0c;结果装完发现该报错还是报…

2026/10/20 7:28:02 阅读更多 →
从Python基础到深度学习:手写神经网络与框架实战入门

从Python基础到深度学习:手写神经网络与框架实战入门

1. 从零到一&#xff1a;为什么大多数人学完Python基础后依然碰不了深度学习我带过不少刚入门的朋友&#xff0c;发现一个特别普遍的现象&#xff1a;Python语法学得挺溜&#xff0c;列表推导式、装饰器、生成器都能写&#xff0c;但一打开深度学习框架的官方文档就懵了。满屏的…

2026/10/20 7:27:02 阅读更多 →
产品经理必懂的RAG七大核心概念:从零掌握大模型知识库应用

产品经理必懂的RAG七大核心概念:从零掌握大模型知识库应用

做AI产品这行&#xff0c;经常收到同行的提问&#xff1a;我是产品经理&#xff0c;不懂算法&#xff0c;怎么和研发聊&#xff1f;我的答案一直很简单——从RAG入手。RAG&#xff08;检索增强生成&#xff09;是当前大模型落地概率最高、见效最快、可控性最强的一条技术路线&a…

2026/10/20 7:27:02 阅读更多 →

最新新闻

CODE V数码相机镜头设计:从规格约束到公差分析全流程

CODE V数码相机镜头设计:从规格约束到公差分析全流程

简介&#xff1a;资源围绕CODE V软件设计数码相机镜头的完整流程展开&#xff0c;面向光学设计入门者及需要了解镜头规格、优化指标的工程师。文档从一台定焦VGA数码相机的设计规格出发&#xff0c;详细讲解了像面尺寸、像素大小、焦距、视场角等关键参数&#xff0c;并说明如何…

2026/10/20 9:02:37 阅读更多 →
M实验室与C公司深度适配:推理框架与算子优化的生态拐点

M实验室与C公司深度适配:推理框架与算子优化的生态拐点

这周几个技术群的讨论热度&#xff0c;几乎都集中在一条生态合作消息上&#xff1a;以开源推理模型出名的M实验室&#xff0c;和做AI处理器、服务器与基础计算平台起家的C公司&#xff0c;官宣在推理框架、算子优化、开发者工具三个层面做了深度适配。圈子里有人直接说&#xf…

2026/10/20 9:02:37 阅读更多 →
C语言switch case用法详解:从if-else嵌套到状态机与跳转表优化

C语言switch case用法详解:从if-else嵌套到状态机与跳转表优化

刚接触C语言的同学&#xff0c;十个里有八个会被if-else连环嵌套折磨到眼晕。特别是当你辛辛苦苦写了七八层判断&#xff0c;回头一看代码缩进都快到屏幕右边缘了&#xff0c;那种心情我太懂了。其实C语言早就给了你一个处理"多选一"场景的利器——switch case语句。…

2026/10/20 9:02:37 阅读更多 →
中小规模ASR私有化部署:从10路到50路的硬件配置与全链路优化

中小规模ASR私有化部署:从10路到50路的硬件配置与全链路优化

1. 这不是买服务器&#xff0c;而是给语音识别系统“搭舞台”——中小规模ASR私有化部署的真实逻辑你搜“10路、30路、50路实时语音识别怎么配服务器”&#xff0c;说明你已经跨过了“要不要上ASR”的决策门槛&#xff0c;正站在工程落地的门口&#xff1a;手上有真实业务场景—…

2026/10/20 9:02:37 阅读更多 →
2026年Agent元年:大模型应用开发从提示词工程到工程化落地

2026年Agent元年:大模型应用开发从提示词工程到工程化落地

说实话&#xff0c;这两年经常被问到同一个问题&#xff1a;2026年才开始学AI大模型开发&#xff0c;会不会太晚了&#xff1f;我的答案通常是反着来的——真正该担心晚的&#xff0c;不是“会不会调接口”&#xff0c;而是“能不能把一个Agent从PPT做到生产环境”。如果你只是…

2026/10/20 9:02:37 阅读更多 →
Protege进阶:推理机、SWRL与SPARQL从入门到避坑

Protege进阶:推理机、SWRL与SPARQL从入门到避坑

简介&#xff1a;面向已经掌握Protege基础操作和推理验证的读者&#xff0c;这份进阶教程以动物园本体构建为贯穿案例&#xff0c;围绕个体编辑、数据属性&#xff08;datatype property&#xff09;和对象属性&#xff08;如Belonging&#xff09;设定展开&#xff0c;详细演示…

2026/10/20 9:01:37 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →