请考虑以下数据:
ARR=[2,3,5,7,11,13,17,19]
N=100
给定的输出应为0,因为n%2=0且arr[0]=2.

因为数组是排序的,所以我想利用这一点,设计一种复杂度小于O(N)的算法,通过迭代整个数组并首先找到i,使n%arr[i]=0.

我立刻想到了使用改进的二进制搜索,其复杂性与常规二进制搜索(O(Logn))相同,后者的作用与常规二进制搜索相同,后者在每次迭代中将搜索间隔一分为二,但略有修改.下面是我使用的实现:

public int SmallestFactorIndex(int n)
{
    int left = 0;
    int right = max;
    int index = -1;

    while (left <= right)
    {
        int middle = (right - left) / 2 + left;
        int middleValue = sieve[middle];

        if (n % middleValue == 0)
        {
            index = middle;
            right = middle - 1;
        }
        else if (middleValue < n)
        {
            left = middle + 1;
        }
        else
        {
            right = middle - 1;
        }
    }

    return index;
}

Max表示数组的长度-1,而Sieve是素数的排序array. 除了二进制搜索之外,如果当前数字除以n,我不会立即返回该索引,而是通过将右边界移到中间来继续搜索比当前数字更小的数字.所有其他部分的工作方式基本相同. 我不认为我可以利用数组只由质数组成的事实,但我可能错了.

推荐答案

我想将此操作设置为log(N)操作

O(log n)通常与二进制算法相关联:您在某个中点处分割数据集;然后基于此中点决定保留哪一半,丢弃哪一半,并重复保留的一半,直到您将结果归零.

当数据被预先排序时,这是有效的great(是的,耶)and可以知道一项(就它自己!)以明确地解决查询.这就是我们的麻烦.比方说,如果n是286(2x11x13),那么2、11和13中的任何一个都是potential个解,并且通过二进制搜索到达其中任何一个上都不会告诉我们我们完成了搜索,直到我们完全完成搜索……我们还得判断所有的东西.

抽象到一般情况,这建议在数组上进行简单的二进制搜索是not good enough by itself,因为简单地找到A解并不会停止对THE解的搜索.

但如果我们事先知道结果的话就can work了.也就是说,如果我们可以在O(Logn)时间内找到最小的素因数(不考虑索引)--如果我们知道我们要寻找的值是2,而不是11或13--那么我们也可以在O(Logn)时间内搜索数组,而O(Logn)+O(Logn)仍然是O(Logn).


现在事情变得有点棘手了,因为我们必须考虑如何将来自输入变量的"n"与质数组的"n"分开.

如果我们看一下输入,完全分解一个数字肯定是NOT O(Logn)--众所周知,许多重要的密码算法依赖于这一点更糟的是much.

但我们不需要充分考虑这个数字.我们只需要first(最小的)素数.这显然可以做得更好一点.但它足够好吗?不幸的是,我认为答案仍然是否定的.

读一读快速复习,我认为对于平均/典型情况,我们很可能can快于线性时间,但我不确定对每一种情况都是可能的,而且复杂性看起来像will only be faster if the numbers we're using are large.


好消息是我认为我们可以得到O(sqrt n)来找到第一个素数.

时间复杂度为O更糟糕的是,现在"n"涉及的是every integer到该值,而不仅仅是预先计算的素数数组的长度(小得多).

因此,对于典型的n个输入(这个数字是一个完全的猜测,但您可以编写一些代码来验证和更正它),线性搜索可能是您所能做的最好的 Select .


说到编写代码来预先验证输入,这就引出了下一个选项:

O(1)

如果您可以对可能的输入数据设置某种合理的界限,那么完全预先计算每个候选整数的结果并将这些值放入O(1)字典中并不是不可能的.即使是一百万个候选人也只会占用大约8MB的内存.

Csharp相关问答推荐

为什么在GuardationRule的收件箱函数中,decode.TryParse(valueString,out valueParsed)在给出1.0.1时返回true?

ASP.NET Core:如何在IPageFilter中注入ApplicationDbContext

哪个nuget包含SecurityStampValidatorOptions

LINQ无法翻译SQLFunctions方法

编写DataAnnotations自定义验证器的多种方法

我需要两个属性类吗

为什么C#Bigbit不总是相同的比特长度?

如何从HttpContext获取请求正文

需要澄清C#的Clean Architecture解决方案模板的AuditableEntityInterceptor类

(乌龙)1&#比c#中的UL&#慢吗?

默认情况下,.NET通用主机(Host.CreateDefaultBuilder)中是否包含UseConsoleLifetime?

如何使datagridview的列具有响应性,以便不是所有列都更改其宽度

HttpClient 415不支持的媒体类型错误

.NET 8在appsettings.json中核心使用词典URI、URI&>

如何在一次数据库调用中为ASP.NET核心身份用户加载角色

在.NET Maui中,Flyoutindow/Hamburger菜单可以在shell 之外实现吗?

如何将 colored颜色 转换为KnownColor名称?

获取应用程序版本信息时出现奇怪信息

如何对列表<;列表>;使用集合表达式?

C#LINQ多行条件