歌曲时长配对问题 | 豆包MarsCode AI刷题

125 阅读6分钟

题目解析

题目描述: 小F有一个由歌曲组成的列表,每首歌的持续时间用数组 time 表示,其中第 i 首歌的时长为 time[i] 秒。她想知道列表中有多少对歌曲的总持续时间能够被 10 整除。具体来说,我们希望找到所有满足 i < j(time[i] + time[j]) % 10 == 0 的配对。

样例

  • 输入:time = [3, 2, 15, 1, 4]
  • 输出:0
  • 输入:time = [10, 20, 30]
  • 输出:3
  • 输入:time = [7, 3, 5, 5, 10]
  • 输出:2

思路: 要找到所有满足 (time[i] + time[j]) % 10 == 0 的配对,可以通过以下步骤来解决问题:

  1. 计算余数:对于每个 time[i],计算其除以 10 的余数 time[i] % 10
  2. 使用哈希表记录余数:使用一个哈希表来记录每个余数出现的次数。
  3. 查找配对:对于每个 time[i],查找哈希表中是否存在一个余数 10 - (time[i] % 10),如果存在,则说明找到了一个配对。

代码实现

python

def solution(time: list) -> int:
    # 计算每个时间的余数
    remainder_count = [0] * 10
    for t in time:
        remainder_count[t % 10] += 1
    
    count = 0
    
    # 处理余数为0和5的情况
    count += (remainder_count[0] * (remainder_count[0] - 1)) // 2
    count += (remainder_count[5] * (remainder_count[5] - 1)) // 2
    
    # 处理其他余数
    for i in range(1, 5):
        count += remainder_count[i] * remainder_count[10 - i]
    
    return count

if __name__ == '__main__':
    print(solution(time=[3, 2, 15, 1, 4]) == 0)
    print(solution(time=[10, 20, 30]) == 3)
    print(solution(time=[7, 3, 5, 5, 10]) == 2)

代码详解

  1. 计算余数

    remainder_count = [0] * 10
    for t in time:
        remainder_count[t % 10] += 1
    

    这段代码计算每个时间的余数,并将余数的出现次数记录在 remainder_count 列表中。

  2. 处理余数为0和5的情况

    count += (remainder_count[0] * (remainder_count[0] - 1)) // 2
    count += (remainder_count[5] * (remainder_count[5] - 1)) // 2
    

    余数为0和5的情况需要特殊处理,因为它们只能与自己配对。使用组合公式 C(n, 2) = n * (n - 1) / 2 来计算配对数。

  3. 处理其他余数

    for i in range(1, 5):
        count += remainder_count[i] * remainder_count[10 - i]
    

    对于其他余数,查找哈希表中是否存在一个余数 10 - (time[i] % 10),如果存在,则说明找到了一个配对。

知识总结

新知识点

1. 哈希表的应用

解释

  • 哈希表(Hash Table)是一种数据结构,用于存储键值对(key-value pairs),支持高效的插入、删除和查找操作。哈希表通过哈希函数将键映射到数组的索引位置,从而实现快速访问。
  • 数组作为哈希表:在某些情况下,可以使用固定大小的数组来模拟哈希表,特别是当键的范围有限且已知时。

如何运用

  • 在这道题目中:我们使用了一个长度为10的数组 remainder_count 来记录每个余数的出现次数。数组的索引对应余数,值对应该余数出现的次数。

  • 代码示例

    remainder_count = [0] * 10
    for t in time:
        remainder_count[t % 10] += 1
    

2. 余数计算

解释

  • 余数(Modulo Operation):通过 a % b 计算 a 除以 b 的余数。余数计算在许多算法中都有应用,特别是在需要周期性或循环性处理的问题中。
  • 用途:余数计算可以用来简化问题,将大数问题转化为小数问题,便于处理和计算。

如何运用

  • 在这道题目中:我们通过 time[i] % 10 计算每首歌的时长除以10的余数,用于判断哪些歌曲的时长和可以被10整除。

  • 代码示例

    remainder_count = [0] * 10
    for t in time:
        remainder_count[t % 10] += 1
    

3. 组合公式

解释

  • 组合公式:组合公式 C(n, 2) = n * (n - 1) / 2 用于计算从 n 个元素中选出2个元素的组合数。组合数在概率论、组合数学等领域有广泛应用。
  • 用途:组合公式可以用来计算特定条件下的一对或多对组合数,特别适用于需要计算配对数的问题。

如何运用

  • 在这道题目中:我们使用组合公式来计算余数为0和5的歌曲对数,因为它们只能与自己配对。

  • 代码示例

    count += (remainder_count[0] * (remainder_count[0] - 1)) // 2
    count += (remainder_count[5] * (remainder_count[5] - 1)) // 2
    

4. 边界条件处理

解释

  • 边界条件:边界条件是指输入数据在极端情况下的处理,如空输入、单个元素等。处理边界条件可以确保程序在各种输入下都能正确运行,提高程序的健壮性。
  • 用途:边界条件处理是编写健壮代码的重要部分,确保程序在各种输入下都能正确运行。

如何运用

  • 在这道题目中:我们在函数开始时检查输入列表的长度是否小于2,确保至少有两个元素才能进行配对。

  • 代码示例

    def solution(time: list) -> int:
        if len(time) < 2:
            return 0
        # 其他代码...
    

学习建议

  1. 理解哈希表的应用:哈希表在处理查找问题时非常高效,熟练掌握其用法可以简化很多算法问题。
  2. 组合公式:组合公式在计算配对数时非常有用,理解其背后的数学原理有助于解决类似问题。
  3. 余数计算:余数计算是基础的数学知识,但在编程中经常需要结合具体问题进行应用。

使用时可能出现的问题及解决方法

  1. 边界条件处理不当

    • 问题:当输入的 time 列表为空或只有一个元素时,代码可能会出错或返回不正确的结果。

    • 解决方法:在函数开始时添加边界条件检查,确保 time 列表至少有两个元素。

  2. 余数为0和5的处理错误

    • 问题:在处理余数为0和5的情况时,组合公式 C(n, 2) = n * (n - 1) / 2 可能会被误用或遗漏。

    • 解决方法:确保正确使用组合公式,并且不要遗漏对余数为0和5的处理。

  3. 余数配对计算错误

    • 问题:在计算其他余数的配对时,可能会遗漏某些配对或重复计算。

    • 解决方法:确保在循环中正确计算配对数,并且不要重复计算。

  4. 数据类型问题

    • 问题:在计算过程中,可能会出现整数除法的结果不正确。

    • 解决方法:确保使用整数除法 // 而不是浮点数除法 /