题目解析:数字匹配问题 | 豆包MarsCode AI刷题

1 阅读5分钟

数字匹配问题

一、问题分析

在这个问题中,我们需要从一组数字中两两配对,使得每对数字的差的绝对值大于等于给定的差异值 M。同时,每个数字只能参与一次配对,不能被重复使用。因此,问题的核心在于如何找到最多满足条件的配对数。

配对规则中的差异值限制意味着我们不能随意配对,而是需要在保证差异值大于等于 M 的情况下进行选择。这种限制对配对的顺序提出了要求,因此需要一种方法来系统地筛选出满足条件的配对组合。

我们的目标是设计一种高效的算法,既能保证满足配对规则,又能最大化配对数量。在分析过程中,可以发现通过排序和遍历的方式能够有效简化问题,同时保证计算的准确性。

二、思路解析

首先,我们将数字序列按照升序排序。排序的目的是方便比较相邻数字的差值,并且更容易找到满足差异值要求的数字配对。排序后的数字序列为后续的遍历和配对提供了基础。

接着,使用双指针的方法进行遍历。一个指针从序列的起始位置开始,另一个指针从起始位置之后逐渐向后移动。双指针法能够高效地找到满足差值要求的数字对,同时避免重复使用数字。每次找到符合条件的配对时,两个指针同时移动;若条件不满足,则只移动后指针以扩大差值。

整个算法采用贪心策略,每次尽量选择当前最小的未配对数字进行配对,从而最大化满足条件的配对数量。通过排序和双指针的结合,我们可以在 O(N log N) 的时间复杂度内解决这个问题,同时保证解决方案的正确性和效率。

三、代码详解

以下是基于上述思路的 Python 实现:

def solution(N: int, M: int, X: list) -> int:
    # 1. 对数字序列进行升序排序
    X.sort()
    
    # 2. 初始化两个指针
    i = 0          # 左指针,指向当前待配对的第一个数字
    j = N // 2     # 右指针,指向可能配对的第二个数字
    count = 0      # 配对计数
    
    # 3. 遍历数字序列,尝试进行配对
    while i < N // 2 and j < N:
        if X[j] - X[i] >= M:
            # 找到一个有效的配对
            count += 1
            i += 1
            j += 1
        else:
            # 差值不够,移动右指针寻找更大的差值
            j += 1
    
    return count

if __name__ == '__main__':
    # 测试样例
    print(solution(N=4, M=2, X=[1, 3, 3, 7]) == 2)       # 输出: True
    print(solution(N=5, M=5, X=[10, 9, 5, 8, 7]) == 1)   # 输出: True
    print(solution(N=6, M=3, X=[2, 4, 6, 8, 10, 12]) == 3) # 输出: True

代码的核心思路是利用排序和双指针法实现高效的数字配对。首先,我们对输入的数字序列 X 进行升序排序,这一步的时间复杂度为 O(N log N),目的是确保数字的排列顺序有序,方便后续查找符合条件的配对。接着,我们初始化两个指针:i 指向当前待配对的数字,初始值为序列的第一个位置;j 指向可能配对的数字,初始值为第二个位置。随后,我们使用一个 while 循环遍历整个序列,尝试找到所有满足配对条件的数字对。在每次循环中,我们比较 X[j] - X[i] 是否大于等于给定的差异值 M,如果满足条件,则记录这对数字为一个有效配对,配对计数器 count 增加 1,同时将两个指针都向前移动一位,以避免重复使用数字;如果条件不满足,仅移动右指针 j,继续寻找可能的配对候选数字。这种双指针的方式确保了每次配对选择都是局部最优,符合贪心策略的思路。整个遍历过程的时间复杂度为 O(N),加上排序的复杂度,总体复杂度为 O(N log N),能够在较短时间内解决问题。最终返回的 count 值即为满足条件的最大配对数。

四、总结

这个问题的核心在于通过一组规则找到数字的最大配对数量。规则要求配对的两个数字的差值必须大于等于给定的差异值 M,同时每个数字只能被使用一次。通过问题分析可以发现,简单的暴力方法效率较低,不能满足较大数据规模的需求,因此需要设计一种更加高效的算法。排序和双指针结合的贪心策略,为问题的求解提供了一种有效且简单的思路。

通过将数字序列进行升序排序,我们能够确保在配对过程中,较小的数字始终被优先匹配,同时减少了不必要的重复比较。双指针的使用使得配对过程变得高效而灵活,一个指针用于定位当前待配对的数字,另一个指针用于搜索满足条件的候选数字。贪心策略在每一步都选择当前最优的配对方案,从而保证配对数量的最大化。