数字匹配问题 | 豆包MarsCode AI刷题

143 阅读5分钟

数字匹配问题

问题描述

小F手中有一串数字,他希望这些数字能按照一定的规则两两配对。配对的规则如下:

  • 数字对中的两个数字的差的绝对值必须大于等于给定的差异值M。
  • 每个数字只能被配对一次,不能出现在其他的数字对中。

小F想知道给定的数字中,最多能成功配对出多少对数字。

例如,对于数字[1, 3, 3, 7]和差异值M = 2,最多可以配对两对数字:(1, 3)和(3, 7)。

测试样例

样例1:

输入:N = 4, M = 2, X = [1, 3, 3, 7] 输出:2

样例2:

输入:N = 5, M = 5, X = [10, 9, 5, 8, 7] 输出:1

样例3:

输入:N = 6, M = 3, X = [2, 4, 6, 8, 10, 12] 输出:3

解题思路

为了最大化配对的数量,我们可以先对数组进行排序,然后尝试从最小的数字开始配对,寻找满足条件的最近的较大数字。这种方法可以确保我们尽可能多地利用数字进行配对。

算法实现

以下是基于上述思路的C++代码实现:

#include <vector>
#include <algorithm>
#include <cmath>

int solution(int N, int M, std::vector<int>& X) {
    std::sort(X.begin(), X.end()); // 对数组进行排序
    int pairs = 0;
    int i = 0; // 指向当前尝试配对的较小数字
    int j = 1; // 指向尝试找到的较大数字

    while (j < N) {
        if (X[j] - X[i] >= M) { // 如果满足配对条件
            pairs++; // 成功配对
            i++; // 移动到下一个数字
            j++; // 继续寻找下一个配对
        } else {
            j++; // 如果不满足条件,尝试下一个较大的数字
        }
        if (i == j) j++; // 避免i和j指向同一个数字
    }
    return pairs;
}

#include <iostream>

int main() {
    std::vector<int> X1 = {1, 3, 3, 7};
    std::cout << solution(4, 2, X1) << std::endl; // 输出 2

    std::vector<int> X2 = {10, 9, 5, 8, 7};
    std::cout << solution(5, 5, X2) << std::endl; // 输出 1

    std::vector<int> X3 = {2, 4, 6, 8, 10, 12};
    std::cout << solution(6, 3, X3) << std::endl; // 输出 3

    return 0;
}

总结

这个问题的关键在于如何有效地配对数字以最大化配对数量。通过对数组进行排序,我们可以确保每次尝试配对时都是从最小的未配对数字开始,寻找满足条件的最近的较大数字。这种方法不仅简单,而且效率较高,能够在O(N log N)的时间复杂度内解决问题,其中N是数组的长度。

数字匹配问题的扩展讨论

问题的复杂性

数字匹配问题虽然看似简单,但实际上涉及到贪心算法和排序算法的结合使用。问题的核心在于如何在满足特定条件(即数字对中的两个数字的差的绝对值必须大于等于给定的差异值M)的情况下,最大化配对的数量。这个问题的复杂性在于需要在全局范围内考虑最优解,而不仅仅是局部最优。

贪心算法的选择

在本问题中,选择贪心算法是基于以下考虑:一旦两个数字被配对,它们就不能再与其他数字配对。因此,我们的目标是尽可能早地配对较小的数字,以便为较大的数字留下更多的配对机会。这种策略有助于最大化整体的配对数量。

排序的重要性

排序是解决这个问题的关键步骤之一。通过对数组进行排序,我们可以确保在尝试配对时总是从最小的未配对数字开始,这样可以最大化利用每个数字的配对机会。排序后的数组使得我们可以线性地遍历数组,寻找满足条件的配对,从而提高了算法的效率。

算法的效率

本算法的时间复杂度主要由排序步骤决定,为O(N log N),其中N是数组的长度。在排序完成后,遍历数组以寻找配对的过程是线性的,即O(N)。因此,整个算法的时间复杂度为O(N log N),这对于大多数实际应用来说是可接受的。

算法的局限性

尽管贪心算法在本问题中表现良好,但它并不总是能够找到全局最优解。在某些情况下,可能需要更复杂的算法(如动态规划)来确保找到最优解。然而,对于本问题,贪心算法提供了一个简单且有效的解决方案。

实际应用

这类问题在实际应用中非常常见,例如在资源分配、任务调度等领域。在这些场景中,我们需要在有限的资源或时间内尽可能多地完成任务或分配资源。通过类似的方法,我们可以有效地解决这些实际问题。

结论

数字匹配问题是一个典型的贪心算法应用场景,通过对数组进行排序和线性遍历,我们可以有效地找到最多的配对数量。这种方法不仅简单易懂,而且在大多数情况下能够提供满意的解决方案。然而,对于更复杂的问题,可能需要考虑更高级的算法技术。