news 2026/10/2 19:56:58

从二分到堆排序:LeetCode每日一题一周串联复盘

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从二分到堆排序:LeetCode每日一题一周串联复盘

这周(2/23到3/1)的LeetCode每日一题刷下来,整体节奏挺有意思的:周初是二分查找和前缀和,中间切到滑动窗口和双指针,周五进了动态规划,周六玩堆和桶排序,最后周日拿周赛430做了一次完整的复盘。周一那天我搜题解的时候,看到搜索联想里蹦出来一条“073爱吃香蕉的狒狒”,愣了一下才反应过来——说的应该是LeetCode 873(爱吃香蕉的珂珂/Koko Eating Bananas,题号有时被记成073),搜索词被念歪了。不过这个别称倒是给了我一个灵感:与其散着刷题,不如把一周的题目串成一条线,每天围绕一个核心算法主题,哪怕题目难度有起伏,知识结构也能一直保持连贯。

这篇就把这周的刷题记录整理出来。如果你是正在准备算法面试、或者刚开始跟每日一题但总觉得刷了就忘的读者,可以参考一下我这一周的题单顺序、每道题的推导思路、还有实际提交中踩过的坑。我不太喜欢写那种“思路+代码”就完事的题解,那样下一周照着做还是会卡住。我更想聊清楚一个问题:这道题为什么要用这个算法,以及它的边界到底在哪里。

1. 这一周的题单规划:为什么按“二分→前缀和→滑动窗口→双指针→DP→堆/桶”来刷

先说个观察:LeetCode官方的每日一题,很多时候并不是按照知识点循序渐进出的,可能昨天还在练树,今天突然跳到状压DP。对于想靠每日一题保持手感的人来说,这其实是好事,因为够随机;但如果你想从一周的题里总结出一点可复用的东西,就得自己动手重新排个序。

我这周的做法很简单:先把这一周要做的题过一遍题号,按算法标签分成六类,然后硬生生排出了一个“从易到难、知识点相邻”的顺序——周一二分,周二前缀和,周三滑动窗口,周四双指针,周五动态规划,周六堆/桶排序,周日留出来做周赛复盘。下面是实际执行的题单总览:

日期核心主题代表题目主要考察点
周一二分查找爱吃香蕉的珂珂(875)单调性判断、check函数设计、向上取整
周二前缀和 + 哈希表和为K的子数组(560)前缀和做差、哈希表计数、负数处理
周三滑动窗口无重复字符的最长子串(3)窗口收缩时机、O(n)双指针
周四排序 + 双指针三数之和(15)排序后夹逼、三重去重
周五动态规划最长递增子序列(300)状态转移、贪心二分优化
周六堆 / 桶排序前K个高频元素(347)TopK问题、两种解法对比
周日周赛复盘周赛430错题整理、边界条件总结

这个顺序不是随便定的。二分和前缀和都涉及“快速缩小问题范围”的思维,相邻刷比较容易迁移;滑动窗口和双指针又是一对孪生兄弟——都是通过维护左右边界来减少重复计算,放在周三周四正好互相参照;周五的LIS是经典的DP题,但它的最优解又用到了二分,能和周一的二分形成呼应;周六的TopK则是堆和桶排序的对比,属于面试里出现频率极高的“手撕题”。

如果你是自己安排题单,我建议也按“相邻知识点有重叠”来排,比如“前缀和 → 差分数组 → 滑动窗口”或者“二分答案 → 最小化最大值 → 贪心验证”。这样一周刷下来,你会发现很多题目只是同一个算法思想换了件外衣,记忆会牢固很多。

2. 2/23 周一:爱吃香蕉的珂珂,二分查找的单调性才是解题钥匙

这道题我最早是在准备笔试时遇到的,当时的印象是“原来二分还能这样用”:不是在一组有序数据里找某个值,而是在一个连续整数区间里找满足条件的最小值。题目说的是,有n堆香蕉,第i堆有piles[i]根,珂珂每小时最多吃k根,但一堆香蕉必须在一个小时内吃完(也就是如果这一堆剩下不足k根,她还是要花整整一小时)。现在要求在h小时内吃完,问最小的k是多少。

2.1 为什么能二分:速度和时间之间存在单调关系

很多二分题的第一难点不在代码,而在“能不能意识到这是二分”。珂珂的吃速k越大,吃完所有香蕉所需的总时间就越小,这是一个严格单调递减的关系。换句话说,存在一个临界值k0:当k < k0时总时间大于h,当k >= k0时总时间小于等于h。我们要找的正是这个k0。

既然具备了单调性,就可以在速度区间上做二分。k的最小值是1(再慢也要吃),最大值是max(piles)(因为最大的那一堆无论如何也得花一整小时,k再大也不会减少超过这一堆所需的时间,所以上限取max(piles)即可,没必要写成10^9这种魔数)。每次取mid,写一个check(mid)判断“用mid的速度能不能在h小时内吃完”,然后根据真假收缩左右边界。

check函数是二分答案题的灵魂。这里需要计算所有堆耗费的总小时数:

def check(k: int) -> bool: hours = 0 for pile in piles: hours += (pile + k - 1) // k # 向上取整的整数写法 return hours <= h

(pile + k - 1) // k这个写法看着不起眼,但比math.ceil(pile / k)好得多——既没有浮点运算,也不会因为pile很大而产生精度问题。

2.2 边界条件与常见错误

我这次提交前先在草稿纸上标了两个边界:一是h恰好等于len(piles)的情况,此时每堆只能花一小时,那唯一可行的速度就是max(piles);二是h很大(比如10^9)的情况,此时答案很可能就是1。这两个边界都能验证二分框架是否正确。

最容易踩的坑有两个。第一个是二分循环的边界写法,我一开始写的是while left <= right,然后if check(mid): right = mid - 1,结果在答案收敛时容易跳过正确值。后来换成标准模板:while left < right,right = mid,left = mid + 1,才稳定通过。第二个坑是check里忘记用向上取整,直接用pile // k,这样会严重低估时间,导致在h较小的情况下误判速度可行,最终返回一个偏小的答案。

这类“在答案区间上二分”的题有一个很通用的扩展方向——“最小化最大值”。比如把香蕉换成一堆货物,把小时换成天数,就是LeetCode 1011“在D天内送达包裹的能力”;把数组切成连续子数组并让子数组和的最大值最小,就是LeetCode 410“分割数组的最大值”。这三道题的骨架完全一样:都在一个连续区间里二分答案,都在check里做一次线性扫描。

3. 2/24 周二:和为K的子数组,前缀和哈希表记录的其实是差值

周二的题是“和为K的子数组”:给定一个整数数组nums和一个整数k,统计连续子数组中和为k的个数。比如nums = [1, 2, 3],k = 3,答案是2([1, 2]和[3])。

3.1 把“区间和”改写成“前缀和之差”

看到连续子数组求和,第一反应通常是滑动窗口,但这里有个隐藏陷阱:数组里可能存在负数。一旦有负数,窗口的“右移变大、左移变小”就不再成立,传统的同向双指针就废了。正确的突破口是前缀和。

设prefix[i]表示nums[0]到nums[i-1]的和(长度为i),那么子数组nums[j..i]的和可以写成prefix[i+1] - prefix[j]。题目要的是这个差值等于k,也就是prefix[i+1] - prefix[j] = k,移项得到prefix[j] = prefix[i+1] - k。换句话说,当我们从左往右遍历数组并不断累加前缀和s时,我们真正需要回答的问题是:之前出现过多少个前缀和等于s - k?这个“历史上出现过多少次”的查询,正是哈希表最擅长的事。

class Solution: def subarraySum(self, nums: List[int], k: int) -> int: count = 0 prefix = 0 # key: 前缀和的值,value: 该前缀和出现的次数 map = {0: 1} for num in nums: prefix += num if prefix - k in map: count += map[prefix - k] map[prefix] = map.get(prefix, 0) + 1 return count

3.2 两个反直觉的细节

第一个细节是为什么要初始化map = {0: 1}。因为prefix[j]是有可能等于0的:如果从数组开头到当前位置的前缀和恰好等于k,那么prefix - k = 0,而这个“0前缀和”其实出现在所有元素之前,所以必须在遍历开始前就记上这一笔。

第二个细节是“边算边存”而非“先算完再存”。很多人容易搞混:把所有的前缀和先求出来,然后再两两做差。那样不仅要先花 O(n) 建数组,还要用二层循环去枚举起点和终点,直接回到O(n²)暴力。而边遍历边查哈希表,可以保证“查到的都是当前下标之前出现过的前缀和”,自然满足子数组必须连续、且结束于当前位置这一要求,整体复杂度降到 O(n)。

这道题的扩展思路很值得掌握:把sum == k改成sum % k == 0,就变成了LeetCode 974“和可被K整除的子数组”,处理时只需要把“差值是否等于k”改成“两个前缀和对k取模是否相等”,并注意负数取模的修正。再比如LeetCode 525“连续数组”,把0和1映射成-1和1,问题就变成“和为0的最长连续子数组”,同样用前缀和哈希表,只是统计的内容从“次数”变成了“第一次出现的位置”。

4. 2/25 周三:无重复字符的最长子串,滑动窗口的左指针什么时候收缩

周三的“无重复字符的最长子串”算得上滑动窗口的入门题。给定一个字符串s,找出其中不含重复字符的最长子串的长度。比如s = "abcabcbb",答案是3("abc")。

这道题的暴力做法是枚举所有起点和终点,对每个子串检查字符是否重复,复杂度 O(n³),实在说不过去。滑动窗口之所以能优化到 O(n),是因为它发现了两个重要性质:第一,右指针右移时,窗口如果合法,那么它就不会比之前的合法窗口短;第二,当窗口内出现重复字符时,左指针不需要逐回退地重构窗口,而只需要一路右移,直到把那个造成重复的字符挤出去。

class Solution: def lengthOfLongestSubstring(self, s: str) -> int: n = len(s) if n <= 1: return n left = 0 ans = 0 # 用数组模拟哈希表,ASCII字符范围是128 cnt = [0] * 128 for right in range(n): idx = ord(s[right]) cnt[idx] += 1 while cnt[idx] > 1: # 窗口内已经存在该字符,需要收缩左边界 cnt[ord(s[left])] -= 1 left += 1 ans = max(ans, right - left + 1) return ans

这里的核心问题就是:什么时候收缩左指针?答案不是“这个字符出现过就收缩”,而是“当前窗口内这个字符的计数大于1就收缩”。因为一个字符可能在窗口外出现过无数次,但只要它在窗口内出现一次,就不影响合法性。所以判断条件要用窗口内的计数,而不是全局的字符集合。

还有个小细节:字符串不一定是纯ASCII,如果遇到Unicode字符,用[0] * 128的数组就会越界。稳妥写法是用collections.Counter或defaultdict(int)。我就有一次在本地跑得好好的,提交后因为一个中文测试案例直接数组越界,后来改成了Counter才通过。

如果你感觉这道题已经吃透了,可以试试把“字符不能重复”扩展成“最多包含K个不同字符”——那就是LeetCode 340,本质还是滑动窗口,只是收缩条件从“某个字符计数>1”变成了“不同字符数量>K”。这类题练熟了以后,面试考“最小覆盖子串”(LeetCode 76)也能更快上手。

5. 2/26 周四:三数之和,排序后双指针的去重才是灵魂

周四是“三数之和”:给定整数数组nums,找出所有满足nums[i] + nums[j] + nums[k] = 0的三元组,并且要求不重复。这道题的难点不在找,而在“不重复”三个字上。

5.1 排序 + 固定一个数 + 双指针夹逼

如果直接哈希表做,也能找出和为0的三元组,但去重非常痛苦。更常见也更优雅的做法是:先排序,然后固定第一个数nums[i],在剩余区间[i+1, n-1]里用双指针找两数之和等于-nums[i]。排序的意义在于:双指针能根据“当前两数之和偏大还是偏小”来移动左右指针,而且排序后的相同元素聚在一起,去重变得非常直观。

class Solution: def threeSum(self, nums: List[int]) -> List[List[int]]: n = len(nums) if n < 3: return [] nums.sort() res = [] for i in range(n - 2): # 剪枝:第一个数都大于0,三数之和不可能为0 if nums[i] > 0: break # 外层去重:跳过重复的第一个数 if i > 0 and nums[i] == nums[i - 1]: continue target = -nums[i] left, right = i + 1, n - 1 while left < right: s = nums[left] + nums[right] if s < target: left += 1 elif s > target: right -= 1 else: res.append([nums[i], nums[left], nums[right]]) # 内层去重:找到一组后跳过重复的第二个/第三个数 while left < right and nums[left] == nums[left + 1]: left += 1 while left < right and nums[right] == nums[right - 1]: right -= 1 left += 1 right -= 1 return res

5.2 去重位置比去重本身更重要

这道题让我反复WA的地方有三处。第一处是外层去重必须用nums[i] == nums[i - 1],而不是nums[i] == nums[i + 1]——后者会把一些合法三元组漏掉,因为当i是重复元素中的第一个时,它和后面的组合是有可能和前面的组合不同的(虽然最后结果可能一样,但仔细推演排序后的顺序就知道,判断当前元素和它前一个是否相同才是合法的“这一轮是否处理过相同打头”的判断)。第二处是内层找到一组合法三元组后,必须同时移动左右指针,并且分别跳过所有重复值,只移动一边会导致同一组三元组被重复统计。第三处是一个小剪枝:if nums[i] > 0: break,因为排序后nums[i]是三元组里最小的数,它都大于0了,后面全是正数,和不可能为0。

“排序+双指针”的套路不仅能解三数之和,还能用于LeetCode 16“最接近的三数之和”和LeetCode 18“四数之和”。如果你想以后碰到“N数之和”不慌,我建议把三数之和的去重逻辑吃透,N数之和只是在外层多套几层循环,每一层都沿用“跳过重复元素”的思想。

6. 2/27 周五:最长递增子序列,从O(n²)动态规划到O(nlogn)贪心二分

周五的“最长递增子序列”,给定数组nums,求最长严格递增子序列的长度。子序列可以不连续,但元素的相对顺序要保持。这道题有两个层次,可以说是垂直考察DP基本功和优化能力的经典题。

6.1 动态规划:状态定义决定转移方向

我先说DP做法。定义dp[i]为“以nums[i]结尾的最长递增子序列长度”。为什么一定要以nums[i]结尾?因为只有这样才能利用“前一个元素比nums[i]小”这一条件来转移:

dp[i] = 1 + max(dp[j]),其中 j < i 且 nums[j] < nums[i]

初始时每个dp[i] = 1(子序列至少包含自身),答案就是max(dp)。这个做法的时间复杂度是 O(n²),空间 O(n)。对于笔试来说这个复杂度在小数据量下问题不大,但如果n到了10^5,O(n²)直接超时。

6.2 贪心二分:维护“同长度子序列的最小末尾值”

面试官真正想听的通常是优化版。这里有一个很有洞察力的贪心:定义tails[i]为“长度为i+1的递增子序列中,末尾元素的最小值”。这个数组天然是严格递增的——如果长度为3的递增子序列的最小末尾值,不可能比长度为2的还小(否则长度2的子序列可以延长成长度3)。所以当我们遍历新元素x时,只需要在tails里二分查找第一个大于等于x的位置,把它替换成x;如果x比tails所有元素都大,就说明可以接到最长子序列后面,tails直接追加。

class Solution: def lengthOfLIS(self, nums: List[int]) -> int: import bisect tails = [] for x in nums: pos = bisect.bisect_left(tails, x) # 第一个 >= x 的位置 if pos == len(tails): tails.append(x) else: tails[pos] = x return len(tails)

要注意的是,tails里存的并不是最终的最长递增子序列本身,它只是在动态维护“每个长度下的最小末尾值”。我初学的时候一度以为替换操作会破坏序列,后来才明白:长度信息是不会丢的,替换只是给后续更长的子序列留出空间。复杂度从 O(n²) 降到 O(nlogn),这个优化在笔试面试里非常值钱。

如果你想把LIS的扩展练透,可以试试LeetCode 354“俄罗斯套娃信封问题”,本质上是对宽度升序、高度降序排序后求高度的LIS;还有LeetCode 646“最长数对链”,也是同样的套路。DP题最怕的就是只会背转移方程,不理解状态为什么这么定义。这一题的状态转移有两个前提——一个是“以当前元素结尾”,另一个是“只从前面的更小元素转移”,理解这两个前提后,换一道题也不会手足无措。

7. 2/28 周六:前K个高频元素,堆排序和桶排序之争

周六的“前K个高频元素”是网络热词里反复出现的高频题。给定一个整数数组nums和一个整数k,返回出现频率前k高的元素。这道题考查的点很集中:哈希表统计 + TopK取数。

7.1 最小堆维护TopK:每次只和堆顶比

统计完频率后,最简单的想法是“所有元素按频率从大到小排序,取前K个”,时间复杂度 O(nlogn)。但TopK问题有一个更省时间的思路:维护一个大小为k的最小堆,堆顶是当前候选里频率最小的那个。遍历所有元素时,如果堆没满就直接入堆;如果堆满了,而且当前元素的频率比堆顶大,就替换堆顶。这样堆里始终保存着“到目前为止频率最高的K个元素”。

class Solution: def topKFrequent(self, nums: List[int], k: int) -> List[int]: import heapq from collections import Counter cnt = Counter(nums) heap = [] for num, freq in cnt.items(): if len(heap) < k: heapq.heappush(heap, (freq, num)) elif freq > heap[0][0]: heapq.heapreplace(heap, (freq, num)) return [num for _, num in heap]

Python的heapq默认是最小堆,所以元组要写成(freq, num),让频率作为排序第一关键字。复杂度是 O(nlogk),当k远小于n时比全排序快不少。

7.2 桶排序:频率做桶下标,从高往低扫

另一种思路是桶排序。因为元素出现频率的最大值不会超过n,所以可以申请一个长度为n+1的桶数组,下标为频率,桶里存放对应频率的元素。然后从大到小遍历每个频率桶,取出元素直到凑够k个。

class Solution: def topKFrequent(self, nums: List[int], k: int) -> List[int]: from collections import Counter cnt = Counter(nums) n = len(nums) bucket = [[] for _ in range(n + 1)] for num, freq in cnt.items(): bucket[freq].append(num) res = [] for freq in range(n, 0, -1): if bucket[freq]: res.extend(bucket[freq]) if len(res) >= k: return res[:k] return res

桶排序的时间复杂度是 O(n),但空间上多了一个长度为n+1的桶数组。堆排和桶排哪个好?要分场景:如果n很大但k很小,堆排更省空间且不用关心最高频率的分布;如果频率值整体不大、桶数组内存可接受,桶排的线性时间在理论上更有优势。面试时能让面试官看到你清楚两种方案的取舍,通常比直接闷头写一种更加分。

这一题还有个容易被忽略的变体:如果元素不是整数而是单词,要求“出现频率相同则按字典序升序”,那就是LeetCode 692“前K个高频单词”。解法基本一致,堆的元组改成(-freq, word),或者桶里存单词后排序。

8. 3/1 周日:周赛430之后的复盘,我总结出四个记录习惯

周日是周赛430。我不打算在文章里复述每道题的题面,因为周赛题目会出现在官方题库里,当场复盘价值最高。我更想聊的是“赛后复盘怎么做才不至于白打一场”——这一点是我从这周的每日一题练习中明显感觉到受益的部分。

8.1 错题本里应该有的四类记录

我现在的复盘习惯是:每场周赛结束后,把四类东西写进错题本(或笔记目录)。第一,边界条件:比如周三滑动窗口那道题的while cnt[idx] > 1,我第一次写成了while idx in window,逻辑虽然对,但不知道用计数来判断就会在复杂场景下出错;第二,推导错误:比如周二前缀和那道题,我一开始忘了初始化map = {0: 1},导致从数组开头就满足条件的子数组全部漏掉;第三,复杂度误判:周五的LIS,我一开始想当然写了O(n²)的DP,后来看到n <= 10^5才意识到必须优化;第四,模板盲区:比如二分的left < right和right = mid这套模板,我原本一直用left <= right,结果周一就踩坑。

整理错题本不为别的,就是为了下一次周赛前快速把变体扫一遍。我见过有人错题本记得特别多,但全是把代码贴一遍,没有任何注释;也有人每题只写“哦这里看错了”,两周后就忘光。真正有用的记录,是“为什么错 + 下一次怎么避免 + 同类题还有哪几道”。

8.2 每周一次“闭卷重写”比刷十道新题更有用

周日除了复盘周赛,我还会从这一周的每日一题里抽一道“本周代表题”闭卷重写。这周我抽的是“爱吃香蕉的珂珂”,因为它是整周里最能串联知识点的题目:二分找单调区间、check函数线性扫描、向上取整手法,同时它又是“最小化最大值”这类题的鼻祖。闭卷重写的要求是不看题解、不看笔记,从读题到提交通过一气呵成。这个过程能在十分钟内暴露我所有的理解漏洞——比如今天我就发现自己对while left < right的终止条件还是有点凭感觉,于是又花时间把几个变体全部过了一遍。

周赛成绩起伏很正常,但复盘的频率决定你是在“原地打转”还是在“螺旋上升”。我个人的原则是:每周雷打不动只做一次完整复盘,但一次复盘必须包含一道完全独立重写的题。这个习惯坚持了大概两个月,效果比我想象中明显——很多原来容易在周赛里卡住的边界条件,现在差不多长在肌肉记忆里了。

这一周刷下来,最大的感受是:每日一题真正的价值不在“今天AC了几道”,而在“这一周里你是否让几道题之间产生了联系”。二分、前缀和、滑动窗口、双指针、DP、堆桶排序,单独看都是常见的算法标签,但把它们排在一周里连续练,你会发现它们在思维上有很多暗线是相通的——比如二分的单调性验证、DP的状态转移、堆的“只和堆顶比”,本质上都是在找一种“更聪明的枚举方式”。

最后分享一个小技巧:现在每次提交每日一题之前,我会强制自己先默想出三个边界用例——空输入、极端大值、重复元素成群的情况。这个方法让我的提交错误率降了很多。你可以从这个习惯开始试试,比一次性刷十道题更管用。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 19:55:55

鲲鹏云ARM架构Hadoop集群搭建与OBS对接实验指南

简介&#xff1a;这份鲲鹏云大数据实验docx面向高校学生与云计算初学者&#xff0c;聚焦在华为云环境中从零搭建Hadoop集群的完整实践。内容以实验报告形式记录&#xff0c;涵盖购买ECS与OBS、获取AK/SK认证密钥、配置节点互信与SSH免密登录、创建目录结构、编写core-site.xml等…

作者头像 李华
网站建设 2026/10/2 19:55:50

SpringBoot+Vue+MySQL毕设项目:从源码跑通到答辩的全流程避坑指南

又到一年毕设季&#xff0c;后台收到一堆留言问“SpringBootVueMySQL”这类题目的源码怎么跑起来、论文怎么写、答辩怎么讲。说句实在话&#xff0c;这套技术栈在本科毕设里确实占了半边天&#xff0c;但大部分同学拿到源码之后&#xff0c;要么卡在环境配置上&#xff0c;要么…

作者头像 李华
网站建设 2026/10/2 19:53:56

C# Winform影院售票管理系统数据库设计实战:锁座与事务

简介&#xff1a;一款基于C# Winform的影院售票管理系统&#xff0c;附带完整数据库文件&#xff0c;开发环境为VS2012与SQL Server 2012&#xff1b;系统面向C#窗体应用学习者、高校课程设计及毕业设计人群&#xff0c;可帮助快速上手多窗体管理类项目。数据库文件只需在SQL S…

作者头像 李华
网站建设 2026/10/2 19:53:27

MobaXterm远程工作台:SSH/X11/RDP一体化实战指南

1. 为什么MobaXterm成了Linux远程工作的“隐形推手”——不是因为它免费&#xff0c;而是它把复杂事做简单了你有没有过这种体验&#xff1a;刚配好一台Ubuntu服务器&#xff0c;想连上去跑个df -h看看磁盘&#xff0c;结果卡在SSH密钥权限报错上&#xff1b;或者在公司内网用R…

作者头像 李华
网站建设 2026/10/2 19:52:29

OpenShell终端增强:从智能补全到多机同步的命令行效率革命

1. 项目概述&#xff1a;OpenShell到底是个什么“壳”如果你跟我一样&#xff0c;每天要在终端里泡几个小时&#xff0c;时间长了就会发现一个尴尬的事实&#xff1a;原生Shell能做的事不少&#xff0c;但真正让我烦心的不是命令写不对&#xff0c;而是那些高频操作太碎——历史…

作者头像 李华
网站建设 2026/10/2 19:51:45

Jev 是什么?AI 编程接入实战与避坑指南

1. Jev 到底是个什么东西&#xff1a;从热搜词里还原它的真实面貌最近一段时间&#xff0c;不管是在技术群还是各种开发者社区&#xff0c;"Jev"这个词出现的频率突然高了起来。很多人第一次看到它&#xff0c;脑子里冒出的第一个问号就是&#xff1a;这又是个新出的…

作者头像 李华