每天一小步 | 豆包MarsCode AI刷题

57 阅读5分钟

学习方法与心得

题目解析

问题描述

题目要求根据参与抢红包的金额对多个人进行排序。如果金额相同,则按参与抢红包的顺序进行排名。具体来说:

  1. 抢到金额越多的人排名越前;
  2. 若两人抢到的金额相同,则根据他们抢红包的顺序决定排名,先抢的排前面。

解题思路

1. 数据存储
  • 我们需要保存每个人的名字和抢到的金额。可以将名字和金额一起存储在一个列表中,使用 Map.Entry<String, Integer> 来记录每个人的名字和金额。
2. 排序规则
  • 排序时,首先根据抢到的金额进行降序排序;
  • 如果金额相同,则根据原始顺序(即数组中的顺序)进行排序。
3. 排序操作
  • 使用 List.sort 方法对数据进行排序,排序时:
    • 使用 b.getValue().compareTo(a.getValue()) 来确保金额从大到小排列;
    • 如果金额相同,通过比较原始顺序来保持先后次序。
4. 提取结果
  • 排序完成后,提取排序后的参与者名字,作为最终的结果返回。

代码实现

import java.util.*;

public class Main {
    public static List<String> solution(int n, List<String> s, List<Integer> x) {
        // 创建一个列表来存储参与者的信息
        List<Map.Entry<String, Integer>> participants = new ArrayList<>();
        
        // 将参与者的名字和抢到的金额存储到列表中
        for (int i = 0; i < n; i++) {
            participants.add(new AbstractMap.SimpleEntry<>(s.get(i), x.get(i)));
        }
        
        // 根据题目要求进行排序
        participants.sort((a, b) -> {
            // 首先按照金额降序排序
            int cmp = b.getValue().compareTo(a.getValue());
            // 如果金额相同,按照抢红包的顺序排序
            if (cmp == 0) {
                return s.indexOf(a.getKey()) - s.indexOf(b.getKey());
            }
            return cmp;
        });
        
        // 提取参与者的名字并返回
        List<String> result = new ArrayList<>();
        for (Map.Entry<String, Integer> entry : participants) {
            result.add(entry.getKey());
        }
        
        return result;
    }

    public static void main(String[] args) {
        // 测试用例
        System.out.println(solution(4, Arrays.asList("a", "b", "c", "d"), Arrays.asList(1, 2, 2, 1)).equals(Arrays.asList("b", "c", "a", "d")));
        System.out.println(solution(3, Arrays.asList("x", "y", "z"), Arrays.asList(100, 200, 200)).equals(Arrays.asList("y", "z", "x")));
        System.out.println(solution(5, Arrays.asList("m", "n", "o", "p", "q"), Arrays.asList(50, 50, 30, 30, 20)).equals(Arrays.asList("m", "n", "o", "p", "q")));
    }
}

核心算法分析

1. 时间复杂度

  • 遍历参与者的列表需要 O(n),其中 n 为参与者人数。
  • 排序操作的时间复杂度为 O(n log n)
  • 因此,整个算法的时间复杂度是 O(n log n),其中 n 为参与者人数。

2. 空间复杂度

  • 我们使用了一个列表来存储参与者的名字和抢到的金额,空间复杂度是 O(n)

3. 排序细节

  • 使用 Comparator 来对参与者进行排序,首先按照金额排序,其次根据顺序排序。
  • 这种排序方式保证了题目中要求的“金额相同按顺序排”的规则。

知识总结

通过这道题目,我总结了以下几个重要知识点:

1. 如何使用 Map.Entry 存储一对数据

  • 使用 Map.Entry 来存储一对数据(如名字和金额)是很常见的方式,适用于需要同时记录两个相关数据的场景。

2. Comparator 的应用

  • 排序是常见的操作,在这道题中,使用 Comparator 通过自定义排序规则来实现排序,保证了金额相同的情况下,按照原始顺序排序。

3. 排序与时间复杂度

  • 排序算法的时间复杂度通常是 O(n log n),是处理大量数据时的常见瓶颈。在面对更大规模的数据时,需要注意性能优化。

4. List 和 ArrayList 的使用

  • 使用 ArrayList 存储和操作动态数据。其索引访问速度为 O(1),非常适合用于这种排序、查找等频繁操作的场景。

学习计划

1. 强化排序算法的理解

  • 学习并理解不同的排序算法,如快排、归并排序、堆排序等,了解它们的时间复杂度和适用场景。

2. 学习如何使用 Comparator

  • 深入理解 Comparator 的使用,掌握如何通过自定义排序规则来对数据进行灵活的排序。

3. 编写更多与数据结构相关的题目

  • 针对列表、集合、映射等数据结构进行更多的实践,尤其是在实际问题中如何高效地存储和排序数据。

工具运用

1. 豆包MarsCode AI解析功能

  • 利用 AI 提供的题目解析功能,快速理解题目中的难点与技巧,节省时间。

2. 调试与优化

  • 在处理数据量较大的问题时,学习如何通过分析时间复杂度、空间复杂度来优化程序,尤其是在排序等操作中。

3. 代码重构与改进

  • 学习如何根据题目的不同要求,灵活地调整数据结构和算法设计,提升代码的可读性和效率。

学习建议

  1. 先理解题目,再写代码
  • 在动手写代码前,花时间理解题目的要求和细节,确保自己明白每个步骤的目的。
  1. 熟练掌握排序与比较
  • 排序和比较是大部分算法题的基础,多做一些排序相关的题目,掌握如何使用不同的比较器。
  1. 思考时间和空间复杂度
  • 在解决问题时,要时刻考虑时间复杂度和空间复杂度,尤其是在面对大规模数据时。通过优化算法,使代码更加高效。

通过这道题目,希望大家能够更加熟练地掌握排序操作,以及如何利用 Comparator 自定义排序规则,提升自己的编程能力!