小C和小U算法题笔记

83 阅读4分钟

做题笔记

问题描述

小C和小U有三个区间:[l₁, r₁]、[l₂, r₂] 和 [l₃, r₃]。他们各自从这三个区间中选择一个自己最喜欢的区间,但不能选择相同的区间。接着,他们会在自己选择的区间内选一个数字,并且这个数字还必须能在对方选择的区间内找到。为了让彼此更高兴,他们希望选择的两个数字的和尽可能大。

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

思路分析

  1. 理解问题:

    • 小C和小U各自从三个区间中选择一个不同的区间。
    • 每个区间是一个连续的数值区间。小C选择的区间和小U选择的区间必须有交集,否则无法找到共同的数字。
    • 选择的数字是从自己选择的区间内选取,并且这个数字必须也在对方的区间内。
    • 小C和小U希望他们选择的数字的和最大。
  2. 关键问题:

    • 对于每一对不同的区间,我们需要找出这两个区间的交集。
    • 交集区间的最大值和最小值是关键:交集区间的最大值越大,和就越大。
    • 对于任意一对区间,交集区间的左端是两个区间左端的最大值,右端是两个区间右端的最小值。
  3. 具体步骤:

    • 考虑所有可能的区间组合(小C选择一个区间,小U选择另一个区间),找到他们的交集区间。
    • 对于每对区间,计算交集区间的最大值和最小值,取交集区间中的最大值和最小值作为两个选定数字。
    • 如果没有交集区间,则该组合无效。
    • 最终结果是所有有效组合的最大和。
  4. 特殊情况:

    • 如果三个区间的交集都为空,即不存在可以共同选择的数字,则输出 -1。

时间复杂度分析:

  • 共有三个区间,选区间的组合总数为 C(3,2)=3C(3, 2) = 3C(3,2)=3。
  • 对每一对区间,计算交集的最大值和最小值的时间复杂度是常数 O(1)O(1)O(1)。
  • 因此,整体的时间复杂度为 O(1)O(1)O(1),即非常高效。

Java代码实现

public class MaxSum {
    
    public static int maxSum(int l1, int r1, int l2, int r2, int l3, int r3) {
        int maxSum = -1;
        
        // 比较区间 [l1, r1][l2, r2]
        if (Math.max(l1, l2) <= Math.min(r1, r2)) {
            int overlapMax = Math.max(l1, l2);
            int overlapMin = Math.min(r1, r2);
            maxSum = Math.max(maxSum, overlapMax + overlapMin);
        }
        
        // 比较区间 [l1, r1][l3, r3]
        if (Math.max(l1, l3) <= Math.min(r1, r3)) {
            int overlapMax = Math.max(l1, l3);
            int overlapMin = Math.min(r1, r3);
            maxSum = Math.max(maxSum, overlapMax + overlapMin);
        }
        
        // 比较区间 [l2, r2][l3, r3]
        if (Math.max(l2, l3) <= Math.min(r2, r3)) {
            int overlapMax = Math.max(l2, l3);
            int overlapMin = Math.min(r2, r3);
            maxSum = Math.max(maxSum, overlapMax + overlapMin);
        }
        
        return maxSum;
    }

    public static void main(String[] args) {
        // 示例1
        System.out.println(maxSum(1, 3, 2, 4, 4, 6)); // 输出:8
        
        // 示例2
        System.out.println(maxSum(1, 2, 2, 3, 3, 4)); // 输出:6
        
        // 示例3
        System.out.println(maxSum(10, 20, 15, 25, 30, 40)); // 输出:40
    }
}

代码解释

  1. 交集计算:

    • 对于任意两个区间 [l₁, r₁] 和 [l₂, r₂],其交集区间的起始位置是 max(l1,l2)\text{max}(l₁, l₂)max(l1​,l2​),终止位置是 min(r1,r2)\text{min}(r₁, r₂)min(r1​,r2​)。
    • 如果 max(l1,l2)≤min(r1,r2)\text{max}(l₁, l₂) \leq \text{min}(r₁, r₂)max(l1​,l2​)≤min(r1​,r2​),说明这两个区间有交集,交集的最大值和最小值可以直接计算。
  2. 计算最大和:

    • 对每一对区间组合,检查它们的交集是否为空。
    • 如果有交集,计算交集区间的最大值和最小值,返回其和。
    • 更新当前的最大和(即选取最优的组合)。
  3. 返回结果:

    • 如果存在有效的交集,返回最大和;否则返回 -1。

总结

  • 通过计算每一对区间的交集并选取最大的交集值,可以高效地找到最大和。
  • 该算法的时间复杂度为 O(1)O(1)O(1),适合这种小范围的区间问题。
  • 关键点在于如何处理交集区间的最大值和最小值,确保选择的数字可以满足题意的条件。