青训营学习收获1 | 豆包MarsCode AI 刷题

137 阅读7分钟

青训营学习收获1

AI 刷题收获:理想火车站定位(难度中)

image.png image.png

1、题目解析

在一个网格状的城市中,我们需要选择一个火车站的位置,使得所有市民到火车站的总曼哈顿距离最短。曼哈顿距离是指在网格上从一个点到另一个点的距离,计算方法为:(|x_1 - x_2| + |y_1 - y_2|)。

输入

  • N: 市民的总人数。
  • M: 可建设火车站的备选位置数。
  • citizens: 一个列表,每个元素是一个元组 ([x_i, y_i]),表示第 i 位市民的居住位置。
  • locations: 一个列表,每个元素是一个元组 ([p_i, q_i]),表示第 i 个备选的火车站位置。

输出

  • 返回最优的火车站位置,使得市民到火车站的总旅行时间最短。如果有多个位置具有相同的最小距离,选择第一次出现的那个。

思路

  1. 初始化: 设置一个变量 min_distance 为无穷大,表示当前最小的总曼哈顿距离。另一个变量 best_location 用于记录最佳位置。
  2. 遍历所有备选位置: 对于每一个备选火车站的位置,计算所有市民到该位置的总曼哈顿距离。
  3. 计算曼哈顿距离: 对于每个市民,计算其到当前火车站位置的曼哈顿距离,并累加得到总距离。
  4. 更新最佳位置: 如果当前总距离小于 min_distance,则更新 min_distancebest_location
  5. 返回结果: 遍历结束后,返回 best_location

深入思考

假设有以下市民和备选火车站位置:

  • 市民位置:([1, 2], [3, 4], [5, 6])
  • 备选位置:([4, 5], [6, 7])

计算每个备选位置的总曼哈顿距离:

  • 对于位置 ([4, 5]):

    • 距离:(|1-4| + |2-5| = 6)
    • 距离:(|3-4| + |4-5| = 2)
    • 距离:(|5-4| + |6-5| = 2)
    • 总距离:(6 + 2 + 2 = 10)
  • 对于位置 ([6, 7]):

    • 距离:(|1-6| + |2-7| = 10)
    • 距离:(|3-6| + |4-7| = 6)
    • 距离:(|5-6| + |6-7| = 2)
    • 总距离:(10 + 6 + 2 = 18)

最佳位置为 ([4, 5]) 因为其总距离最小。

代码详解

def solution(n, m, citizens, locations):
    min_distance = float('inf')
    best_location = None

    for location in locations:
        total_distance = 0
        for citizen in citizens:
            total_distance += abs(citizen[0] - location[0]) + abs(citizen[1] - location[1])
        
        if total_distance < min_distance:
            min_distance = total_distance
            best_location = location

    return best_location

if __name__ == "__main__":
    # Test cases
    citizens1 = [[-1, -1], [-1, 1], [1, -1], [1, 1]]
    locations1 = [[3, 2], [1, 0], [0, 0]]
    print(solution(4, 3, citizens1, locations1) == [1, 0])

代码说明

  • 初始化min_distance 用于存储当前最小的总距离,初始为无穷大。
  • 遍历位置: 对每个备选位置,计算所有市民的总曼哈顿距离。
  • 更新逻辑: 如果找到更小的总距离,则更新最佳位置。
  • 返回结果: 最后返回最佳位置。
  • 通过这种方法,我们可以有效地找到最优的火车站建设位置。

运行结果

image.png

2、知识总结

曼哈顿距离

概念: 曼哈顿距离是指在一个网格状的城市中,从一个点到另一个点的距离。计算方式为: [ d = |x_1 - x_2| + |y_1 - y_2| ]

理解: 想象你在一个城市中行走,只能沿着街道和巷道移动,不能穿越建筑物。曼哈顿距离就是这种情况下的最短路径距离。

应用: 曼哈顿距离常用于网格地图中的路径规划、机器学习中的特征距离计算等。

解题思路解析

  1. 遍历法: 对每个可能的火车站位置,计算所有市民到该位置的总距离。这种方法虽然简单直接,但在处理大规模数据时可能效率不高。
  2. 优化思路: 可以考虑通过排序或其他数学方法优化计算过程,以减少不必要的计算。

对入门同学的学习建议

  1. 理解基础概念: 在学习算法时,首先要理解基础的数学概念,比如曼哈顿距离。这些概念是解决问题的基础。
  2. 从简单问题入手: 开始时选择简单的问题进行练习,逐步积累经验和信心。
  3. 多动手实践: 通过编写代码来加深对算法的理解。实践是掌握编程技能的关键。
  4. 分析优化: 学会分析代码的效率,寻找优化的可能性。随着经验的积累,尝试改进算法。
  5. 学习他人经验: 通过阅读别人的代码和解题思路,学习不同的解决方法和技巧。

3、学习计划

制定刷题计划

  1. 设定目标: 每周设定一个小目标,比如解决5道不同类型的算法题。逐步增加难度,循序渐进。
  2. 主题学习: 每周专注于一个主题,如“排序算法”或“动态规划”。通过集中学习,深入理解每个主题的核心概念。
  3. 时间安排: 每天固定一个时间段进行刷题,比如晚上8点到9点,形成习惯。
  4. 进度跟踪: 使用工具(如Excel或Trello)记录已完成的题目、遇到的困难和解决方案,方便回顾和总结。

高效学习方法

  1. 分解问题: 把复杂的问题分解成多个小问题,逐个解决,最后合并解决方案。
  2. 模拟面试: 定期进行模拟面试,限时解决问题,提高在压力下的解题能力。
  3. 讨论与分享: 参与讨论组或学习小组,与他人分享解题思路,互相学习。
  4. 多种解法: 尝试用不同的方法解决同一道题,比较它们的优缺点,寻找最优解。

利用错题进行针对性学习

  1. 错题本: 记录每道做错的题目,分析错误原因,针对性地复习相关知识点。
  2. 定期复习: 记得复习错题本,确保不会在相同的地方跌倒两次。
  3. 深度剖析: 对于反复出错的题目,尝试从不同角度理解问题。
  4. 反思总结: 每次解决错题后,写下自己的反思和总结,记录新的收获和改进思路。

个性化学习建议

  1. 兴趣驱动: 选择感兴趣的题目类型进行练习。
  2. 灵活调整: 根据自己的进步情况和兴趣,调整学习计划,保持新鲜感。
  3. 奖励机制: 设定小奖励机制,比如完成某个阶段目标后给小奖励。

4、工具运用

结合刷题与其他学习资源

  1. 在线平台刷题

    • LeetCode、CodeSignal、HackerRank: 这些平台提供大量的算法和数据结构题目,可以帮助你在实践中提高编程能力。
    • 每天坚持做几道题,从简单题开始,逐步挑战中等和困难题。关注题解讨论区,学习他人的解题思路。
  2. 视频教程

    • YouTube、Coursera、edX: 有许多免费的算法和数据结构课程,可以帮助你更直观地理解复杂概念。
    • 结合视频中的例子,自己动手实现一遍,加深理解。
  3. 学习社区

    • Stack Overflow、Reddit: 在这些社区中可以提出问题、分享经验、交流学习心得。
    • 积极参与讨论,帮助他人解决问题的同时也能提高自己的水平。
  4. 笔记整理

    • 使用工具如 Notion、Evernote、OneNote 来整理学习笔记。
    • 记录每道题的解题思路、遇到的困难和解决方案,方便日后复习。
  5. 项目实践

    • 将所学算法应用到实际项目中,比如数据分析、安全开发等。
    • 找到一个感兴趣的项目,尝试将算法优化应用其中,验证学习效果。

实用学习建议

  • 制定学习计划: 制定合理的学习计划,设定每日、每周的学习目标,保持持续进步。
  • 多角度学习: 不仅仅依赖一种资源,多角度、多平台学习,形成自己的理解。
  • 定期复习: 定期回顾已学知识,尤其是错题和难题,确保掌握扎实。
  • 动手实践: 理论结合实践,尽量在实际问题中应用所学知识。