1. 红包运气排行榜
问题描述:
小C参与了一场抢红包的游戏,需要对所有参与者进行一次运气排名,规则如下:
- 抢到的金额越多,排名越靠前。
- 如果金额相同,则按照抢红包的顺序进行排名,先抢的排前面。
思路:
- 这是一个基于贪心策略的问题,核心是按照金额降序排序,然后在金额相同的情况下,保持原始顺序。
- 排序策略:由于要处理金额相同的情况,传统的排序会破坏顺序。因此,需要使用稳定排序方法,如
stable_sort,它保证了在排序时,元素间的相对顺序不会改变。
步骤:
- 将所有参与者的名字和抢到的金额存储在一个
pair中,pair<string, int>,并将其加入一个数组。 - 使用
unordered_map存储每个名字对应的索引位置,确保在元素相同的情况下可以按顺序合并金额。 - 对金额进行排序,使用
stable_sort,确保相同金额的元素按原顺序排列。 - 最后输出排序后的名字。
分析:
- 时间复杂度:
O(n log n),主要由于排序操作。stable_sort是稳定排序,保留了相同金额的元素顺序。 - 空间复杂度:
O(n),需要额外的空间存储索引和排序结果。
2. 计算从位置 x 到 y 的最少步数
问题描述:
- 给定整数位置
x和y,从x移动到y的最小步数。每一步的移动幅度可以是-1, 0, 1,但首末两步必须为 1。
思路:
- 这是一个基于动态步长的贪心问题。每一步的步长是连续的,先减小后增加。
- 对于起始位置和目标位置的差值
sub = |x - y|,我们需要确定如何最小化步数。 - 通过贪心策略,每次都尽可能地增加步长,直到累积步长大于等于
sub。
步骤:
- 计算
sub = |x - y|,即目标位置和起始位置之间的差距。 - 逐步增加步长,直到总和大于或等于
sub。 - 如果步长总和恰好等于
sub,则需要2 * step步。否则,需要2 * step + 1步。
分析:
- 时间复杂度:
O(√sub),因为每一步的步长递增,求解步长的过程是线性的。 - 空间复杂度:
O(1),仅需要少量变量。
3. 查找热点数据问题
问题描述:
- 给定一个整数数组
nums和一个整数k,返回其中出现频率前k高的元素,并按升序排列。 - 需要优化算法时间复杂度,要求优于
O(n log n)。
思路:
- 使用频率计数的方法来记录每个元素的出现次数。然后利用**最小堆(优先队列)**来获取出现频率最高的
k个元素。 - 为了保证升序排序,可以先计算出频率并排序,再通过堆操作获取最频繁的
k个元素。
步骤:
- 使用
unordered_map统计每个元素的出现频率。 - 将频率和对应的元素放入最小堆中,并确保堆的大小保持为
k。 - 最后从堆中取出元素,按升序排列并输出。
分析:
- 时间复杂度:
O(n log k),其中n是数组的大小,k是需要输出的频率最高的元素个数。频率统计是O(n),堆的操作是O(log k)。 - 空间复杂度:
O(n),需要存储每个元素的频率和堆。
总结
这些问题涉及了典型的贪心策略应用:
- 红包运气排行榜:通过稳定排序确保相同金额的元素按顺序排列,解决了优先级排序的问题。
- 从位置 x 到 y 的最少步数:使用动态步长和贪心策略,逐步增加步长,直到满足条件。
- 查找热点数据问题:结合哈希表和最小堆,通过频率计数和堆排序获取前
k个频率最高的元素。