如何在不到O(N)的时间内解决这个问题?

How to solve this in less than O(N)?

本文关键字:解决 时间 问题      更新时间:2023-10-16

我有一个排序(升序(元素数组作为输入。我想找出这些元素是否构成一个系列,其中每个当前元素都可以被它之前的所有元素整除。 这是我能想到的O(n(时间内这个问题的明显解决方案:

bool CheckArray(int arr[], int no_of_elements)
{
if (no_of_elements == 1)
return true;
for (int i = 1; i < no_of_elements; i++)
if (arr[i] % arr[i - 1] != 0)
return false;
return true;
}

示例 1:输入:3 6 9 12 输出:假

示例 2:输入:3 6 12 输出:真

有没有办法在不到 O(n( 的时间内做到这一点?如果是,如何?

不可能比 O(n( 做得更好。

每个元素都可以有一个值,用于将解决方案从 true 更改为 false。因此,您至少需要对每个元素执行一个操作来检查它。

因此,您至少将拥有 O(n(。

显然,您需要 O(N( 遍历才能产生true

您可以进行的优化是尽快产生false

我推测(并认为证明会很难,但如果数字是算术分布的,则是正确的(相邻较大的数字对(a,b(不太可能是整数n的形式(a,na(而不是较小的数字。因此,通过首先考虑较大的数字,您可以更快地产生false。换句话说,从最后一个元素运行到第一个元素的循环最终可能会在统计上更快。您必须分析呈现给您函数的典型数字序列。

顺便说一下,你的序言

if (no_of_elements == 1)
return true;

是多余的。