前言
好一阵没怎么参加掘金金石计划了。一方面金石计划暂停了好几个月了,另一方面最近有点忙(其实是比较懒...)
看了下记录,上一篇文章面试官:说说 vue3 的 ref 为什么要用 .value 取值?是去年6月写的。当时花了挺多时间去研究Vue3相关的源码,并试着用文章的方式整理出来。截止目前,阅读量4.2k、点赞30、收藏53,还是蛮有成就感的。
我平时会刷刷LeetCode题目。有时候解不出来,会找官方题解看看,结合题解的注释,试着去理解题目。不过,官方题解有时候理解起来实在是太费劲了,远不如其他人写的题解简单明了。
最近刚好做到一道题:2444. 统计定界子数组的数目。做题的时候觉得有点难,心血来潮地想到可以试着用 Trae AI(之前叫 MarsCode AI)辅助解答下,发现效果还挺好的。题目内容是:
分析题目
首先,分析下题目。
题目给出一个整数数组 nums 和两个整数 minK 以及 maxK ,要我们返回定界子数组的数目。需要注意的是,定界子数组是数组中的一个连续部分,且需要包含两个边界值minK 和 maxK!
题目难度是困难。
题意不难理解,应该如何解题呢?
/**
* @param {number[]} nums
* @param {number} minK
* @param {number} maxK
* @return {number}
*/
var countSubarrays = function(nums, minK, maxK) {
}
这里直接看下官方题解。
官方题解如下:
我们可以用这些数将原数组分割成若干段,每个段内只包含数值在 [minK,maxK] 之间的数字。
对于每个段,我们记 border 为段左边界(为了方便计算,令第 border+1 个数才是段内的第一个数字),然后从左到右遍历时,记当前位置 i 左侧第一个数值等于 minK 的位置是 last_min,左侧第一个数值等于 maxK 的位置是 last_max,那么在这个段内,以 i 为右端点的定界子数组共有 min(last_min,last_max)−border 个。
我们遍历完所有段,将所有以 i 为右端点的定界子数组个数加起来就是答案。
/**
* @param {number[]} nums
* @param {number} minK
* @param {number} maxK
* @return {number}
*/
var countSubarrays = function(nums, minK, maxK) {
let res = 0;
let border = -1, last_min = -1, last_max = -1;
for (let i = 0; i < nums.length; i++) {
if (nums[i] < minK || nums[i] > maxK) {
last_max = -1;
last_min = -1;
border = i;
}
if (nums[i] === minK) {
last_min = i;
}
if (nums[i] === maxK) {
last_max = i;
}
if (last_min !== -1 && last_max !== -1) {
res += Math.min(last_min, last_max) - border;
}
}
return res;
}
代码很简洁,不过也有点难以读懂。
比如,
- last_min 和 last_max 是什么意思?
- 为什么还需要 border?
- 为什么定界子数组共有 min(last_min,last_max)−border 个?
- ...
Trae 解读
在VSCode中,鼠标选中代码,右键"Trae AI" - "Explain Code",
可以看到很快就输出了代码解读了:
而且我们可以在输入框的右边点击切换不同的模型,选择其中最合适的模型:
在 Trae AI 输入的内容中,我们可以看到,
变量初始化:
res:记录最终结果(满足条件的子数组数量)
border:记录最近遇到的超出[minK, maxK]范围的元素位置
last_min:记录最近遇到的等于minK的元素位置
last_max:记录最近遇到的等于maxK的元素位置
关键计算:
res += Math.min(last_min, last_max) - border;
这行代码计算的是:以当前i为右边界,所有可能的左边界数量。左边界必须:
在border之后(确保不包含非法元素)
不超过minK和maxK中较早出现的位置(确保同时包含两者)
Trae 注释的思路很清晰,告诉我们 last_min、last_max、border等变量的含义,以及这行代码计算的是以当前i为右边界,所有可能的左边界数量,而且左边界必须满足以下两个条件:
- 在border之后(确保不包含非法元素)
- 不超过minK和maxK中较早出现的位置(确保同时包含两者)
也就是说,代码会将原数组分割成若干段,每个段内只包含数值在 [minK,maxK] 之间的数字。
跟Trae交流
如果还是不理解,我们可以试着在输入框中跟Trae交流:
- 为什么需要判断last_min !== -1 && last_max !== -1?
- 怎么理解 res += Math.min(last_min, last_max) - border?
不难发现,Trae的思路很清晰,会解释变量的含义、代码的意义等,甚至会在最后结合例子给出解释。
后记
总的来说,Trae AI 集成了 Doubao、DeepSeek-V3等模型,用于代码解读、代码补全等功能很方便,可以帮助我们快速地读懂LeetCode题解。