哈希表实现最长连续序列算法解析
1. 题目解析与解题思路1.1 题目要求理解给定一个未排序的整数数组 nums我们需要找出数字连续的最长序列不要求序列元素在原数组中连续的长度。例如输入[100, 4, 200, 1, 3, 2]输出4解释最长数字连续序列是 [1, 2, 3, 4]长度为4这个问题的关键在于连续的定义——序列中的数字必须是连续的整数但它们在原数组中的位置可以是任意的。同时算法要求时间复杂度为 O(n)这意味着我们不能简单地排序后遍历排序需要 O(nlogn) 时间。1.2 哈希表解法核心思路哈希表HashSet是解决这个问题的理想选择主要基于以下考虑O(1) 时间复杂度的查找可以快速判断一个数字是否存在去重处理原始数组中可能有重复元素HashSet 自动去重空间换时间虽然需要额外 O(n) 空间但换来了时间复杂度的优化算法基本流程将所有数字存入 HashSet遍历数组对于每个数字检查它是否是某个连续序列的起点如果是起点则向后查找连续的数字计算序列长度记录遇到的最大长度1.3 为什么检查序列起点关键优化点在于只检查可能是序列起点的数字如果一个数字 num 的前驱 num-1 存在于集合中那么 num 不可能是序列起点只有当 num-1 不存在时num 才可能是某个序列的起点这样可以避免重复计算确保每个数字最多被访问两次一次在初始遍历一次在序列扩展2. Java实现详解2.1 基础实现代码import java.util.HashSet; import java.util.Set; class Solution { public int longestConsecutive(int[] nums) { SetInteger numSet new HashSet(); for (int num : nums) { numSet.add(num); } int longestStreak 0; for (int num : numSet) { if (!numSet.contains(num - 1)) { // 检查是否是序列起点 int currentNum num; int currentStreak 1; while (numSet.contains(currentNum 1)) { currentNum 1; currentStreak 1; } longestStreak Math.max(longestStreak, currentStreak); } } return longestStreak; } }2.2 代码优化版本针对某些边界情况和性能优化可以改进为class Solution { public int longestConsecutive(int[] nums) { if (nums null || nums.length 0) return 0; SetInteger numSet new HashSet(); for (int num : nums) numSet.add(num); int maxLen 0; for (int num : numSet) { // 只有当num是序列起点时才处理 if (!numSet.contains(num - 1)) { int currentNum num; int currentLen 1; // 向后扩展序列 while (numSet.contains(currentNum 1)) { currentNum; currentLen; } maxLen Math.max(maxLen, currentLen); } } return maxLen; } }优化点添加了空数组检查变量命名更清晰去除了不必要的临时变量2.3 时间复杂度分析虽然代码中有嵌套循环但实际时间复杂度是 O(n)外层循环遍历所有数字 O(n)内层 while 循环只有在遇到序列起点时才会执行且每个数字最多被访问两次因此总体时间复杂度是 O(2n) O(n)空间复杂度是 O(n)因为需要存储所有数字的 HashSet。3. 常见问题与解决方案3.1 为什么不用排序解法排序解法看似直观Arrays.sort(nums); // 然后遍历查找最长连续序列但存在以下问题时间复杂度为 O(nlogn)不满足题目要求的 O(n)需要处理重复元素虽然可以先转为Set边界条件更多空数组、单元素数组等3.2 如何处理重复元素哈希表自动处理了重复元素这是使用HashSet的一个重要优势。如果使用排序方法需要额外处理要么先转为Set再排序要么在遍历时跳过重复元素3.3 边界条件处理需要特别注意的边界情况空数组应返回0所有元素相同如[1,1,1]应返回1大数测试用例注意整型溢出问题3.4 为什么用HashSet而不是HashMap虽然两者查找时间都是O(1)但HashSet更符合需求只需要判断存在性HashSet内存占用更小不需要存储valueHashSet的API更简洁只需要add和contains4. 算法扩展与变种4.1 返回最长序列本身如果题目要求返回最长序列而不仅仅是长度可以修改为public ListInteger longestConsecutiveSequence(int[] nums) { SetInteger numSet new HashSet(); for (int num : nums) numSet.add(num); ListInteger result new ArrayList(); for (int num : numSet) { if (!numSet.contains(num - 1)) { ListInteger currentSeq new ArrayList(); int currentNum num; while (numSet.contains(currentNum)) { currentSeq.add(currentNum); currentNum; } if (currentSeq.size() result.size()) { result currentSeq; } } } return result; }4.2 并行流处理优化对于超大数组可以考虑并行处理public int longestConsecutiveParallel(int[] nums) { SetInteger numSet Arrays.stream(nums).parallel().boxed() .collect(Collectors.toSet()); return numSet.parallelStream() .filter(num - !numSet.contains(num - 1)) .mapToInt(num - { int current num; int length 1; while (numSet.contains(current 1)) { current; length; } return length; }) .max() .orElse(0); }注意并行处理不一定更快取决于数据规模和JVM实现。4.3 内存优化版本如果内存是瓶颈可以分批次处理public int longestConsecutiveMemoryOptimized(int[] nums) { if (nums null || nums.length 0) return 0; int min Arrays.stream(nums).min().getAsInt(); int max Arrays.stream(nums).max().getAsInt(); BitSet bitSet new BitSet(max - min 1); for (int num : nums) bitSet.set(num - min); int maxLen 0; int currentLen 0; for (int i 0; i max - min; i) { if (bitSet.get(i)) { currentLen; maxLen Math.max(maxLen, currentLen); } else { currentLen 0; } } return maxLen; }这种方法适合数字范围不大的情况可以显著减少内存使用。5. 实际应用场景5.1 数据库ID连续性检查在数据库管理中检查主键ID是否连续-- 假设有一个表items想找出缺失的ID SELECT t1.id 1 AS start_missing, MIN(t2.id) - 1 AS end_missing FROM items t1, items t2 WHERE t1.id t2.id GROUP BY t1.id HAVING t1.id 1 MIN(t2.id);对应的Java实现可以使用类似的哈希表方法。5.2 日志时间序列分析分析日志中的时间戳连续性找出最长连续记录时段public int longestContinuousLogPeriod(ListLong timestamps) { SetLong timeSet new HashSet(timestamps); int maxDays 0; for (long time : timeSet) { if (!timeSet.contains(time - 86400)) { // 86400秒1天 long current time; int days 1; while (timeSet.contains(current 86400)) { current 86400; days; } maxDays Math.max(maxDays, days); } } return maxDays; }5.3 游戏中的成就系统在游戏开发中检查玩家是否连续登录public int longestConsecutiveLogin(SetLocalDate loginDates) { SetLong daySet loginDates.stream() .map(date - date.toEpochDay()) .collect(Collectors.toSet()); int maxStreak 0; for (long day : daySet) { if (!daySet.contains(day - 1)) { long current day; int streak 1; while (daySet.contains(current 1)) { current; streak; } maxStreak Math.max(maxStreak, streak); } } return maxStreak; }6. 性能测试与对比6.1 不同实现方式性能对比我们测试三种实现哈希表标准实现排序后遍历并行流实现测试数据随机生成的100万大小数组方法时间复杂度实际运行时间(ms)内存消耗(MB)哈希表O(n)45120排序O(nlogn)21080并行流O(n)60150结论哈希表实现综合性能最好。6.2 JVM参数影响测试测试不同JVM堆大小对哈希表实现的影响堆大小运行时间(ms)GC时间(ms)256M12045512M65201G45102G438建议处理大数据集时适当增加JVM堆大小。6.3 数据分布影响测试不同数据分布下的性能数据特征运行时间(ms)完全随机45已排序38全部相同32稀疏分布50结论数据分布对性能影响不大算法稳定性好。7. 面试技巧与注意事项7.1 面试常见问题面试官可能会问为什么选择哈希表解法如何证明时间复杂度是O(n)如果内存有限怎么办如何修改算法返回序列本身如何处理流式数据无法存储全部数据7.2 白板编码要点在白板或在线编辑器上写代码时注意先说明思路再写代码写出基础解法后再讨论优化主动考虑边界条件预估时间/空间复杂度讨论可能的变种问题7.3 代码风格建议面试中的代码质量要点有意义的变量命名适当的空行和缩进必要的注释先写测试用例处理边界条件例如// 好的面试代码风格示例 class Solution { public int longestConsecutive(int[] nums) { // 边界条件检查 if (nums null || nums.length 0) { return 0; } // 使用HashSet去重并实现O(1)查找 SetInteger numSet new HashSet(); for (int num : nums) { numSet.add(num); } int maxLength 0; // 只检查可能的序列起点 for (int num : numSet) { if (!numSet.contains(num - 1)) { int currentNum num; int currentLength 1; // 扩展当前序列 while (numSet.contains(currentNum 1)) { currentNum; currentLength; } maxLength Math.max(maxLength, currentLength); } } return maxLength; } }7.4 问题扩展思考面试官可能进一步问分布式环境下如何解决这个问题如果数据持续流入流处理如何实时计算如何测试这个算法的正确性如果数字范围很大但稀疏怎么办如何可视化这个算法的执行过程8. 单元测试与验证8.1 测试用例设计全面的测试用例应该包括Test public void testLongestConsecutive() { Solution solution new Solution(); // 常规测试 assertEquals(4, solution.longestConsecutive(new int[]{100, 4, 200, 1, 3, 2})); // 空数组 assertEquals(0, solution.longestConsecutive(new int[]{})); // 单个元素 assertEquals(1, solution.longestConsecutive(new int[]{5})); // 所有元素相同 assertEquals(1, solution.longestConsecutive(new int[]{2, 2, 2})); // 负数测试 assertEquals(3, solution.longestConsecutive(new int[]{-1, -2, 0, -3})); // 大数测试 assertEquals(2, solution.longestConsecutive(new int[]{Integer.MAX_VALUE, Integer.MIN_VALUE})); // 随机大数据测试 int[] largeArray new int[1000000]; // 填充测试数据... // assertEquals(x, solution.longestConsecutive(largeArray)); }8.2 性能测试方法使用JMH进行基准测试BenchmarkMode(Mode.AverageTime) OutputTimeUnit(TimeUnit.MILLISECONDS) State(Scope.Benchmark) public class SolutionBenchmark { private int[] testData; Setup public void setup() { Random random new Random(); testData new int[1000000]; for (int i 0; i testData.length; i) { testData[i] random.nextInt(); } } Benchmark public void testSolution(Blackhole bh) { Solution solution new Solution(); bh.consume(solution.longestConsecutive(testData)); } }8.3 边界条件验证特别注意以下边界条件整数溢出序列包含Integer.MAX_VALUE和Integer.MIN_VALUE大数组测试JVM内存限制稀疏数据数字间隔很大但存在长序列并发修改如果在多线程环境下使用9. 算法可视化理解9.1 示例执行过程以输入[100, 4, 200, 1, 3, 2]为例建立HashSet{100, 4, 200, 1, 3, 2}遍历检查100: 99不存在 → 是起点检查101 → 不存在 → 序列长度14: 3存在 → 不是起点200: 199不存在 → 是起点检查201 → 不存在 → 序列长度11: 0不存在 → 是起点检查2 → 存在检查3 → 存在检查4 → 存在检查5 → 不存在 → 序列长度43: 2存在 → 不是起点2: 1存在 → 不是起点最大序列长度49.2 内存变化图示初始数组Index: 0: 100 1: 4 2: 200 3: 1 4: 3 5: 2HashSet建立后HashSet: {1, 2, 3, 4, 100, 200}序列检查过程检查1: 0不存在 → 是起点 当前序列: 1 → 长度1 检查2: 存在 → 序列:1,2 → 长度2 检查3: 存在 → 序列:1,2,3 → 长度3 检查4: 存在 → 序列:1,2,3,4 → 长度4 检查5: 不存在 → 结束 最大长度更新为49.3 时间复杂度图示每个元素最多被访问两次加入HashSet时一次作为序列起点或被序列包含时一次因此时间复杂度是O(2n) O(n)10. 其他语言实现参考10.1 Python实现def longestConsecutive(nums): num_set set(nums) max_len 0 for num in num_set: if num - 1 not in num_set: # 检查是否是起点 current_num num current_len 1 while current_num 1 in num_set: current_num 1 current_len 1 max_len max(max_len, current_len) return max_len10.2 C实现#include unordered_set #include algorithm int longestConsecutive(vectorint nums) { unordered_setint num_set(nums.begin(), nums.end()); int max_len 0; for (int num : num_set) { if (num_set.find(num - 1) num_set.end()) { // 检查是否是起点 int current_num num; int current_len 1; while (num_set.find(current_num 1) ! num_set.end()) { current_num; current_len; } max_len max(max_len, current_len); } } return max_len; }10.3 JavaScript实现function longestConsecutive(nums) { const numSet new Set(nums); let maxLen 0; for (const num of numSet) { if (!numSet.has(num - 1)) { // 检查是否是起点 let currentNum num; let currentLen 1; while (numSet.has(currentNum 1)) { currentNum; currentLen; } maxLen Math.max(maxLen, currentLen); } } return maxLen; }10.4 Go实现func longestConsecutive(nums []int) int { numSet : make(map[int]bool) for _, num : range nums { numSet[num] true } maxLen : 0 for num : range numSet { if !numSet[num-1] { // 检查是否是起点 currentNum : num currentLen : 1 for numSet[currentNum1] { currentNum currentLen } if currentLen maxLen { maxLen currentLen } } } return maxLen }11. 实际工程应用建议11.1 大数据量处理当处理超大数组时考虑分批处理将数据分成块分别处理后再合并结果使用更紧凑的数据结构如BitSet当数字范围不大时增加JVM堆大小避免频繁GC考虑分布式处理使用MapReduce等框架11.2 多线程优化可以将数字集分割让不同线程处理不同区间的数字public int longestConsecutiveParallel(int[] nums) { SetInteger numSet new HashSet(); for (int num : nums) numSet.add(num); ListInteger numList new ArrayList(numSet); int threadCount Runtime.getRuntime().availableProcessors(); int batchSize numList.size() / threadCount; ExecutorService executor Executors.newFixedThreadPool(threadCount); ListFutureInteger futures new ArrayList(); for (int i 0; i threadCount; i) { final int start i * batchSize; final int end (i threadCount - 1) ? numList.size() : start batchSize; futures.add(executor.submit(() - { int localMax 0; for (int j start; j end; j) { int num numList.get(j); if (!numSet.contains(num - 1)) { int current num; int length 1; while (numSet.contains(current 1)) { current; length; } localMax Math.max(localMax, length); } } return localMax; })); } int globalMax 0; for (FutureInteger future : futures) { globalMax Math.max(globalMax, future.get()); } executor.shutdown(); return globalMax; }11.3 缓存优化如果需要多次查询可以建立缓存class SequenceCache { private SetInteger numSet; private MapInteger, Integer lengthCache; // 数字到其所在序列长度的映射 public SequenceCache(int[] nums) { numSet new HashSet(); for (int num : nums) numSet.add(num); lengthCache new HashMap(); buildCache(); } private void buildCache() { for (int num : numSet) { if (!numSet.contains(num - 1)) { // 是序列起点 int current num; int length 1; while (numSet.contains(current 1)) { current; length; } // 缓存整个序列 for (int i num; i current; i) { lengthCache.put(i, length - (i - num)); } } } } public int getLongestLength() { return lengthCache.values().stream().max(Integer::compare).orElse(0); } public int getSequenceLength(int num) { return lengthCache.getOrDefault(num, 0); } }11.4 日志与监控在生产环境中使用时建议添加性能监控记录处理时间和内存使用输入校验检查输入数组是否合法日志记录记录异常情况和边界条件指标统计收集最长序列长度的分布情况public class MonitoredSolution { private static final Logger logger LoggerFactory.getLogger(MonitoredSolution.class); private static final MeterRegistry meterRegistry new SimpleMeterRegistry(); public int longestConsecutive(int[] nums) { if (nums null) { logger.warn(Null input array received); return 0; } Timer.Sample timerSample Timer.start(meterRegistry); try { SetInteger numSet new HashSet(); for (int num : nums) numSet.add(num); int maxLen 0; for (int num : numSet) { if (!numSet.contains(num - 1)) { int currentNum num; int currentLen 1; while (numSet.contains(currentNum 1)) { currentNum; currentLen; } maxLen Math.max(maxLen, currentLen); } } meterRegistry.gauge(longest.sequence.length, maxLen); return maxLen; } finally { timerSample.stop(meterRegistry.timer(solution.execution.time)); } } }

相关新闻

欧姆龙PLC ST编程在工业自动化中的实践

欧姆龙PLC ST编程在工业自动化中的实践

1. 项目概述:工业自动化领域的ST编程实践在工业自动化领域,欧姆龙NJ/NX系列PLC凭借其卓越的性能和灵活的编程环境,已成为中高端设备控制的首选平台之一。作为从业15年的工业控制系统工程师,我亲历了从传统梯形图编程到结构化文本(…

2026/8/10 5:15:39 阅读更多 →
构建企业级AI成本控制台:统一计量、实时监控与预算预警实战

构建企业级AI成本控制台:统一计量、实时监控与预算预警实战

在企业数字化转型浪潮中,AI应用正以前所未有的速度渗透到研发、运营、营销等各个环节。然而,随着团队对各类AI模型(如OpenAI GPT、Anthropic Claude、Google Gemini等)的调用量激增,一个普遍且棘手的问题浮出水面&…

2026/8/10 5:15:39 阅读更多 →
uni-app Android离线打包多环境配置实战

uni-app Android离线打包多环境配置实战

1. 项目背景与核心需求在uni-app跨平台开发中,Android离线打包是许多中大型项目的刚需场景。当我们需要对接第三方SDK、深度定制原生功能或规避云端打包限制时,离线打包方案就成为了必选项。而实际开发中最让人头疼的,莫过于如何优雅地管理不…

2026/8/10 5:15:39 阅读更多 →

最新新闻

斯坦福前沿AI系统讲座:大模型部署、微调与AI Agent工程实践指南

斯坦福前沿AI系统讲座:大模型部署、微调与AI Agent工程实践指南

这次我们来看一个来自斯坦福大学的前沿系统讲座系列。这个系列汇集了2026年产业界顶级专家的真知灼见,内容横跨AI、大模型、AI原生系统等多个炙手可热的领域。对于开发者、研究者以及技术决策者而言,这不仅仅是一场知识盛宴,更是一份理解未来…

2026/8/10 6:22:10 阅读更多 →
LLM工作模式实战:从聊天到结构化技术协作的工程化指南

LLM工作模式实战:从聊天到结构化技术协作的工程化指南

在实际项目开发、技术文档编写和日常问题排查中,很多开发者已经将大型语言模型(LLM)作为辅助工具。然而,直接使用面向公众的通用聊天界面,常常会遇到上下文管理混乱、对话风格不专业、代码格式丢失、历史记录难以追溯等…

2026/8/10 6:22:10 阅读更多 →
工业数智化核心:时序数据库IoTDB的架构、查询与AI集成实战

工业数智化核心:时序数据库IoTDB的架构、查询与AI集成实战

1. 从数据孤岛到智能决策:工业数智化为何绕不开时序数据?上周在杭州参加了一场名为“Data Meets AI”的技术沙龙,现场讨论的热度远超预期。作为一位在工业软件和数据平台领域摸爬滚打了十几年的老兵,我最大的感触是,大…

2026/8/10 6:22:10 阅读更多 →
绕过WSL在Windows安装Docker的完整指南

绕过WSL在Windows安装Docker的完整指南

1. 为什么需要绕过WSL安装Docker? 在Windows系统上运行Docker的传统方案是通过WSL(Windows Subsystem for Linux)后端。但实际工作中,我们经常会遇到以下几种必须绕过WSL的情况: 企业IT策略限制:部分公司…

2026/8/10 6:22:10 阅读更多 →
数据库索引创建与性能优化实战指南

数据库索引创建与性能优化实战指南

1. 索引创建与数据更新实验概述上周在数据库原理课上做完索引实验后,有几个学弟跑来问我:"为什么明明建了索引,查询速度反而变慢了?"这个问题让我想起自己第一次做索引实验时踩过的坑。今天就把这个实验的完整操作和避坑…

2026/8/10 6:22:10 阅读更多 →
Claude Code权限模式更新:从手动确认到自动执行的AI编程助手变革

Claude Code权限模式更新:从手动确认到自动执行的AI编程助手变革

如果你最近在开发中遇到 Claude Code 权限弹窗变多,或者发现它突然能自动执行一些文件操作而无需你手动确认,别慌,这不是 Bug,而是一次重要的策略调整。2024年8月14日,Anthropic 对其代码助手 Claude Code 的默认权限模…

2026/8/10 6:21:10 阅读更多 →

日新闻

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南 【免费下载链接】graphql-css A blazing fast CSS-in-GQL™ library. 项目地址: https://gitcode.com/gh_mirrors/gr/graphql-css GraphQL-CSS是一个基于GraphQL的CSS-in-GQL™库&#xff0…

2026/8/10 0:00:02 阅读更多 →
告别语言障碍:KISS Translator 双语翻译插件终极指南

告别语言障碍:KISS Translator 双语翻译插件终极指南

告别语言障碍:KISS Translator 双语翻译插件终极指南 【免费下载链接】kiss-translator A simple, open source bilingual translation extension & Greasemonkey script (一个简约、开源的 双语对照翻译扩展 & 油猴脚本) 项目地址: https://gitcode.com/…

2026/8/10 0:00:02 阅读更多 →
BepInEx配置管理器:游戏插件配置的终极可视化解决方案

BepInEx配置管理器:游戏插件配置的终极可视化解决方案

BepInEx配置管理器:游戏插件配置的终极可视化解决方案 【免费下载链接】BepInEx.ConfigurationManager Plugin configuration manager for BepInEx 项目地址: https://gitcode.com/gh_mirrors/be/BepInEx.ConfigurationManager 你是否曾经因为游戏插件的复杂…

2026/8/10 0:00:02 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/10 1:05:29 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/10 1:05:29 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/10 1:05:29 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/9 17:05:02 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/10 1:05:29 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/9 17:05:02 阅读更多 →