青训营X豆包MarsCode 技术训练营第二篇 | 豆包MarsCode AI 刷题

122 阅读5分钟

刷题笔记

学习方法与心得

题目解析

今天我刷了三道题目,分别涉及到数组、矩阵、以及链表的基本操作。每道题目的解法都需要一定的算法技巧,尤其是在优化时间复杂度和空间复杂度方面。下面是我的题目解析:

  1. 问题一:观光景点最大得分

    • 问题分析:题目给定了一组景点评分,并要求我们找到两个景点的最佳组合,使得得分最大。得分公式为 values[i] + values[j] + i - j,其中 i < j。这个问题看似简单,但关键是如何找到最大得分对。直观的暴力解法是双重循环遍历所有 ij 的组合,但这会导致 O(n^2) 的时间复杂度。我们需要寻找一种更高效的方式。
    • 优化思路:我们可以通过一次遍历来优化这个问题。定义一个变量 maxValue 用来存储当前最大得分,遍历过程中不断更新,结合之前的得分和当前值的变化来判断是否能获得更高的得分。最终的时间复杂度为 O(n)
    • 代码实现
      func maxScoreSightseeingPair(values []int) int {
          maxValue, prev := -1<<31, values[0]
          for j := 1; j < len(values); j++ {
              maxValue = max(maxValue, prev + values[j] - (j - 0))
              prev = max(prev, values[j] + j)
          }
          return maxValue
      }
      
      func max(a, b int) int {
          if a > b {
              return a
          }
          return b
      }
      
  2. 问题二:最大矩形面积

    • 问题分析:给定一个数组 h,表示一组矩形的高度。要求我们在其中选择 k 个相邻的矩形,求这 k 个矩形能形成的最大面积。每个矩形的面积为 k × min(h[i], h[i+1], ..., h[i+k-1]),因此问题的关键是如何快速计算 k 个相邻矩形的最小高度。
    • 优化思路:我们可以利用滑动窗口方法,每次计算窗口内的最小值,并更新最大面积。通过一次遍历即可得到每个 k 的最大矩形面积。
    • 代码实现
      func largestRectangleArea(h []int) int {
          n := len(h)
          maxArea := 0
          for k := 1; k <= n; k++ {
              for i := 0; i <= n-k; i++ {
                  minHeight := h[i]
                  for j := i + 1; j < i+k; j++ {
                      minHeight = min(minHeight, h[j])
                  }
                  area := k * minHeight
                  maxArea = max(maxArea, area)
              }
          }
          return maxArea
      }
      
      func min(a, b int) int {
          if a < b {
              return a
          }
          return b
      }
      
  3. 问题三:歌单随机播放

    • 问题分析:题目要求模拟一个特殊的歌单播放规则。首先播放歌单中的第一首歌,然后将它从歌单中移除。如果歌单中还有歌曲,则将当前第一首歌移动到最后一首。这种操作类似于队列的出队和入队操作,我们可以用队列数据结构来模拟这个过程。
    • 优化思路:使用队列模拟歌单的播放过程,每次出队一个元素,再将它插入队列的末尾,直到队列为空。通过队列可以将问题的时间复杂度控制在 O(n)
    • 代码实现
      func shuffleSongs(songs []int) []int {
          queue := append([]int{}, songs...)
          result := []int{}
          for len(queue) > 0 {
              result = append(result, queue[0])
              queue = queue[1:]
              if len(queue) > 0 {
                  queue = append(queue, queue[0])
                  queue = queue[1:]
              }
          }
          return result
      }
      

知识总结

通过今天的刷题,我进一步加深了对以下知识点的理解:

  1. 数组和矩阵的操作:掌握了如何通过滑动窗口技巧来高效计算区间最小值,尤其是在题目二中,对于不同 k 的操作进行了优化,使得时间复杂度降低。
  2. 队列和模拟算法:在题目三中,通过队列模拟歌曲的播放顺序,掌握了队列的基本用法及其在实际问题中的应用。
  3. 时间复杂度的优化:通过一次遍历、滑动窗口、队列等技巧,我能够有效优化暴力解法,减少了不必要的计算,提升了代码的效率。

学习计划

在刷题的过程中,我总结了以下几点高效学习方法:

  1. 制定合理的刷题计划:我计划每天集中刷一道题目,逐步加大难度,先做简单题目,逐步挑战中等难度题。每周复习一次错题,分析错误的原因,并查漏补缺。
  2. 错题复习:错题是最好的学习资源,我会把每一道错题记录下来,分析自己的思路和实现的不足,确保每次错误都能转化为进步的动力。
  3. 多角度思考题目:有些题目我一开始会陷入一种思路,容易走进死胡同。我学会了通过多角度思考,尝试不同的数据结构和算法来解决问题。

工具运用

在学习过程中,我结合了 AI 刷题功能和其他学习资源。AI 刷题提供了快速反馈,可以即时纠正我的错误,并提供优化建议。而通过结合其他学习资源,如算法书籍、在线课程等,我能够更全面地理解每个算法的本质及其应用场景。我还会利用 AI 进行错题的智能分析,快速定位问题所在,提升学习效率。

学习体验与故事

体验与成长

AI 刷题功能极大提高了我的学习效率。以前我刷题时,总是觉得有些题目没头绪,做起来很困难。但是通过 AI 提供的代码解析和优化建议,我能够更快地理解题目,并在每次的刷题过程中积累经验。刷题后,我能够看到自己在编程思维上的进步,代码实现也越来越简洁高效。

刷题故事

有一道题我一开始完全没有思路,几乎放弃了。然后通过 AI 的引导和分析,我逐步理清了思路,并成功完成了这道题。当我把代码提交并看到通过测试时,内心的成就感无与伦比。这个过程让我更加相信,AI 在学习中的帮助是不可忽视的。

AI 认知

AI 技术在教育领域的应用正逐渐改变传统的学习方式。通过 AI 的个性化反馈,学习者能够在短时间内发现并弥补自己的不足,不仅仅是记忆和理解知识点,更是在思维方式和问题解决能力上得到了显著提升。我相信未来 AI 将会是教育领域的重要推动力。