You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何加速数组中可被同组元素整除元素的计数求解程序?

如何优化数组最大整除计数程序以避免超时?

问题背景

给定一个数组,找出最大计数:数组中某个元素的计数定义为数组中可以整除该元素的元素数量。例如数组[2,2,2,5,6,8,9,9]的最大计数为4,因为6或8可被2、2、2及自身整除。

原实现思路:

  • 对数组排序并转换为有序集合
  • 用索引对应元素值的数组记录每个元素的出现次数
  • 双层循环从大到小遍历集合元素,检查与其他元素的整除性并累加计数

约束条件:1 <= arr[i] <= 10000,数组长度最多10000。

原代码通过9/10测试用例,但第10个用例超时,需要优化。


瓶颈分析

原代码的双层循环逻辑时间复杂度为O(k²)(k是集合中不同元素的数量),当k接近10000时,循环次数会达到数千万级别,远超时间限制,这是超时的核心原因。


优化方案

利用元素最大值仅为10000的特性,采用计数数组+倍数遍历的方法,时间复杂度降至O(M log M)(M=10000),效率大幅提升。

具体步骤

  1. 统计元素出现次数:创建大小为10001的数组cnt,cnt[x]表示x在原数组中的出现次数。
  2. 动态规划计算每个元素的计数:创建dp数组,dp[x]初始化为cnt[x](自身的数量)。从小到大遍历每个数i,若cnt[i]>0,则遍历i的所有倍数j(j=2i,3i,...,≤10000),将dp[j] += cnt[i]——因为i能整除j,所以所有i的出现次数都要计入j的计数。
  3. 找最大值:遍历dp数组,取最大值即为答案。

优化后的代码

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int main(void) {
    int arr[] = {2,2,2,5,6,8,9,9};
    int size = sizeof(arr)/sizeof(arr[0]);
    const int MAX_VAL = 10000;

    // 统计每个数的出现次数
    int cnt[MAX_VAL + 1] = {0};
    for (int i = 0; i < size; i++) {
        cnt[arr[i]]++;
    }

    // 计算每个数的最大计数并同步找最大值
    int dp[MAX_VAL + 1] = {0};
    int max_count = 0;
    for (int i = 1; i <= MAX_VAL; i++) {
        dp[i] = cnt[i];
        // 遍历i的所有倍数,累加计数
        for (int j = 2*i; j <= MAX_VAL; j += i) {
            dp[j] += cnt[i];
        }
        // 更新全局最大值
        if (dp[i] > max_count) {
            max_count = dp[i];
        }
    }

    printf("%d", max_count);
    return 0;
}

关键优化点说明

  • 彻底避免了原代码中对集合元素的双层遍历,转而利用倍数关系直接累加,循环次数从数千万级降至1.4万级左右
  • 省略了排序和转集合的步骤,直接通过一次遍历统计元素出现次数,进一步节省时间
  • 最大值计算与计数计算同步进行,无需额外遍历
  • 压缩了数组空间,原代码中10万大小的数组被替换为1万零1大小的数组,减少空间浪费

内容的提问来源于stack exchange,提问作者Agrudge Amicus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 01:01:17