小C和小U| 豆包MarsCode AI刷题

129 阅读4分钟

一、问题描述

有三个区间,分别为:

  • [l_1, r_1][l_2, r_2][l_3, r_3]

小C和小U从这些区间中各自选择一个区间,并且选择的两个区间不可以相同。接着,他们从自己的区间内选择一个数,要求这个数还要能够在对方的区间内找到。他们希望获得两个数的和尽可能大。

我们的任务是帮助小C和小U找到这两个数的和的最大值。如果不存在满足条件的两个数,输出 -1

二、问题分析

  1. 区间重合问题

    • 小C和小U分别从各自的区间中选择一个数。为了保证这个数既能满足自己的区间,又能满足对方的区间,这两个区间必须有重合部分。我们需要找到这些区间的重合部分。
  2. 区间选择

    • 每对区间 [l1, r1][l2, r2],它们的重合部分的最大值将是这两个区间交集的最大值。即,如果这两个区间有交集[l, r],那么r就是所能选择的最大的数。
  3. 目标

    • 两人都选择重合区间中最大的数m,最大和=2*m, 即所求目标。
  4. 边界条件

    • 如果三个区间中,任意两个都没有交集,那么小C和小U无法选取满足条件的数,返回 -1

三、解题思路

  1. 区间重合计算

    • 给定两个区间 [a, b][c, d],它们的交集是 [max(a, c), min(b, d)]。如果 max(a, c) <= min(b, d),说明两个区间有交集,交集的最大值为 min(b, d)
    • 如果没有交集,即 max(a, c) > min(b, d),则两个区间无法选取共同的数,返回 -∞
  2. 重合区间选择

    • 计算每对区间的交集后,取所有交集的最大值。这就是我们选择的最大的数,然后返回这个值的两倍作为最终结果。
    • 如果所有的交集最大值都是无穷小(即没有交集),返回 -1

四、代码实现

import math

def solution(l1: int, r1: int, l2: int, r2: int, l3: int, r3: int) -> int:
    # 计算三个区间对之间的重合部分
    n1 = find_overlap(l1, r1, l2, r2)
    n2 = find_overlap(l2, r2, l3, r3)
    n3 = find_overlap(l3, r3, l1, r1)
    
    # 计算所有重合区间中的最大值
    maximum = max(n1, n2, n3)
    
    # 如果没有重合区间,返回-1
    if math.isinf(maximum) and maximum < 0:
        return -1
    
    # 返回最大重合区间数的两倍
    return maximum * 2

def find_overlap(a: int, b: int, c: int, d: int):
    # 如果重合,返回重合区间内的最大值
    if max(a,c) <= min(b,d):
        return min(b,d)
    # 如果没有重合部分,返回无穷小
    return float('-inf')

if __name__ == '__main__':
    print(solution(1, 3, 2, 4, 4, 6) == 8)  # 输出 8
    print(solution(1, 2, 2, 3, 3, 4) == 6)  # 输出 6
    print(solution(10, 20, 15, 25, 30, 40) == 40)  # 输出 40

五、复杂度分析

  1. 时间复杂度

    • find_overlap 函数每次调用的时间复杂度为 O(1),它只是做了几个条件判断和简单的计算。
    • 由于我们只调用了 find_overlap 三次,整个 solution 函数的时间复杂度是 O(1)
  2. 空间复杂度

    • 函数只使用了常数空间来存储临时变量,因此空间复杂度是 O(1)

六、总结与收获

通过这道题,我学习到了如何处理区间交集的问题,并应用了区间重合计算的方法来解决具体问题。代码实现上,我们通过找出三个区间对的交集,找到最大交集值,并通过简单的数学运算得到最终结果。对于区间类的问题,理解如何高效地计算交集和最大值是非常重要的。

这道题的解法是直接而高效的,并且时间复杂度保持在常数级别,说明在处理一些较为简单的问题时,简洁而直接的解决方案是值得优先考虑的。在实际编程中,良好的代码结构和清晰的思路同样重要。