青训营X豆包MarsCode 技术训练营第四课 | 豆包MarsCode AI 刷题

53 阅读8分钟

题目解析

  • 题目描述:给定一个整数数组 nums 和一个目标整数 target,在数组中找出两个数,使得它们的和等于目标值 target,并返回这两个数的索引。假设每种输入只会对应一个答案,且同一个元素不能重复使用。

  • 思路

    • 暴力解法:使用两层嵌套循环,外层循环遍历数组中的每个元素,内层循环从外层循环当前元素的下一个位置开始遍历数组,对于每一对元素,计算它们的和并与目标值 target 进行比较,如果相等,则返回这两个元素的索引。这种方法简单直接,但时间复杂度较高,为 ,n 是数组的长度,在数据量较大时效率低下。
    • 哈希表解法:遍历数组,对于每个元素 nums[i],计算出它与目标值的差值 complement = target - nums[i],然后查看这个差值是否已经存在于哈希表中。如果存在,说明找到了满足条件的两个数,直接返回当前元素的索引以及差值在哈希表中对应的索引;如果不存在,就将当前元素 nums[i] 及其索引 i 存入哈希表中,继续遍历下一个元素。这样只需遍历一遍数组就能解决问题,时间复杂度降低到 ,空间复杂度取决于哈希表存储的元素数量,一般为 。
  • 代码详解(以哈希表解法为例)

收起

java

复制

import java.util.HashMap;
import java.util.Map;

public class TwoSum {
    public static int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int complement = target - nums[i];
            if (map.containsKey(complement)) {
                return new int[]{map.get(complement), i};
            }
            map.put(nums[i], i);
        }
        return null;
    }

    public static void main(String[] args) {
        int[] nums = {2, 7, 11, 15};
        int target = 9;
        int[] result = twoSum(nums, target);
        if (result!= null) {
            System.out.println("找到的两个数的索引为: [" + result[0] + ", " + result[1] + "]");
        } else {
            System.out.println("未找到满足条件的两个数");
        }
    }
}
  • 首先创建一个 HashMap 用于存储元素值及其对应的索引,在 for 循环中,对于数组 nums 中的每个元素 nums[i],计算出与目标值 target 的差值 complement。接着通过 map.containsKey(complement) 判断差值是否已经在哈希表中,如果在,说明找到了满足条件的两个数,通过 map.get(complement) 获取差值对应的索引,与当前元素的索引 i 组成数组返回。如果差值不在哈希表中,就将当前元素 nums[i] 和它的索引 i 通过 map.put(nums[i], i) 存入哈希表,方便后续查找。最后在 main 方法中进行简单的测试调用。

知识总结

  • 新知识点梳理

    • 哈希表(HashMap)的使用:了解到哈希表是一种基于键值对存储的数据结构,它能够在接近常数时间内实现查找、插入和删除操作(平均时间复杂度为 ),在解决需要快速查找元素是否存在或者根据元素获取对应其他信息的问题时非常有用。
    • 空间换时间的思想:像两数之和这道题,使用哈希表解法通过额外开辟一定的空间来存储元素及其索引,换取了更高效的时间复杂度,从暴力解法的  降低到 ,明白了在算法设计中合理权衡时间和空间的重要性。
  • 理解

    • 哈希表的原理基于哈希函数,它能将键快速映射到对应的存储位置,使得查找等操作变得高效。在实际编程中,掌握好哈希表这种数据结构的基本操作和适用场景,可以帮助我们优化很多算法的效率。而空间换时间的思想,提醒我们在面对不同问题时,要综合考虑数据量、时间和空间的限制等因素,选择最合适的解决方案。
  • 学习建议(针对入门同学)

    • 对于哈希表,要先熟悉它在编程语言中的基本使用方法,比如在 Java 中 HashMap 的常用方法 putgetcontainsKey 等,多通过一些简单的示例代码去练习如何向哈希表中添加元素、根据键获取值以及判断键是否存在等操作。
    • 在理解空间换时间思想时,可以多对比不同解法(像两数之和的暴力解法和哈希表解法)在时间和空间复杂度上的差异,通过分析具体的代码执行过程和复杂度计算,深入体会何时适合运用这种思想来优化算法,并且可以自己尝试去改写一些简单算法题目,运用空间换时间的策略去优化原来的解法,加深理解。

学习计划

  • 制定刷题计划

    • 确定目标和范围:首先明确自己的学习目标,比如是为了应对某种编程语言的面试,还是想要提高特定算法领域(如图论、动态规划等)的能力。然后根据目标确定刷题的范围,例如可以选择某一个在线刷题平台(如 LeetCode、牛客网等)上对应的题目分类板块开始。
    • 分阶段安排:将学习过程划分为不同阶段,初期可以从简单题入手,熟悉基本的语法和常见的数据结构、算法思想,每天安排适量的题目(比如 3 - 5 道),保证每道题都能透彻理解解法思路、代码实现以及时间和空间复杂度分析。中期可以增加难度,开始挑战中等难度的题目,重点锻炼将所学知识灵活运用到不同场景的能力,此时可以适当增加刷题量,每周抽出固定的时间集中刷题(比如每周抽出 2 - 3 天,每天刷 5 - 8 道题),同时做好错题整理和知识点总结。后期针对难题进行攻坚,结合实际应用场景深入理解复杂的算法优化思路,并且可以通过模拟考试的形式(按照规定时间完成一套题目)来检验自己的学习成果,查漏补缺。
    • 定期回顾和巩固:每完成一个阶段或者学习了某个新的知识点、算法后,要定期回顾之前刷过的相关题目,尤其是错题和掌握不扎实的题目,重新做一遍或者思考是否有新的解法,不断巩固知识体系。
  • 利用错题进行针对性学习

    • 整理错题集:当遇到做错的题目时,将题目完整地记录下来,包括题目描述、输入输出示例、自己当时的错误解法以及正确解法等内容,可以使用电子文档或者笔记软件来整理,方便后续查看。
    • 分析错误原因:仔细分析做错的原因,是因为对某个知识点(如数据结构的特性、算法的原理等)不熟悉,还是代码实现细节出现了问题(比如边界条件判断错误、语法错误等),亦或是解题思路本身就不对,明确问题所在才能有针对性地改进。
    • 针对性复习和强化练习:根据分析出的错误原因,回顾相关的知识点,重新学习理解不扎实的部分,然后找一些同类型或者运用了相同知识点的题目进行强化练习,直到彻底掌握,避免下次再犯同样的错误。

工具运用

  • 与其他学习资源结合

    • 教材和课程学习:将 AI 刷题功能与专业的算法教材、线上课程相结合。比如在学习某一个算法章节时,先通过教材或课程系统地学习算法的原理、推导过程以及常见的应用场景,然后利用 AI 刷题功能去查找对应算法的练习题进行实践巩固,在刷题过程中遇到不懂的地方再返回教材或课程中深入学习,形成理论学习与实践操作的良性循环。

    • 技术论坛和社区交流:在刷题时,如果遇到难题或者对某个解法有疑问,可以将问题发布到技术论坛(如 Stack Overflow、掘金等)或者相关的学习社区(如 LeetCode 讨论区等)上,与其他开发者交流探讨,参考别人的思路和经验,同时也可以分享自己通过 AI 刷题总结出的好的解题方法和心得,互相学习进步。

    • 项目实践应用:把从 AI 刷题中学到的算法知识应用到实际的项目开发中,比如在开发一个小型的数据分析项目时,运用排序算法对数据进行预处理、使用查找算法在数据集中检索特定信息等,通过实际项目来加深对算法的理解和掌握,同时也能体会到算法在实际场景中的价值,进一步提高自己的编程能力。

希望以上内容对你有所帮助,你可以根据实际需求选择不同的题目按照这样的方式去进行分析总结等,不断提升自己的编程和算法能力哦。你要是还有具体的想法或者疑问,欢迎随时和我交流呀。