下面我有一个算法,它计算有序数组中所有唯一的整数,但我不确定它是如何使用二进制搜索来做到这一点的?有谁能解释一下是怎么回事吗?谢谢.

int unique(int[] a) {
    int i = 0;
    int count = 0;
    while (i < a.length) {
      i = nextIndex(a, i, a[i]);
      count++;
    }
    return count;
  }

  int nextIndex(int[] a, int l, int target) {
    int r = a.length - 1;
    while (l <= r) {
      int mid = l + (r - l) / 2;
      if (a[mid] == target) l = mid + 1;
      else r = mid - 1;
    }
    return r + 1;
  }

推荐答案

nextIndex方法本质上是一种二进制搜索方法,它搜索目标值的最后一个匹配项,然后返回大于这个值的索引.因此,外部循环将迭代并增加计数,次数与存在唯一值的次数相同.

请注意,只有在分析显示需要时,我才会使用这种复杂的方法.标准方法应该是myValues.Distinct().Count(),这对于无序列表应该更快,并且适用于整型数组以外的类型.

连续的二进制搜索的复杂度应该为O(m log n),其中n是项的总数,m是唯一值的数量.这表明,如果平均重复值少于log n个,则线性搜索应该会更快.这样的线性搜索可能类似于:

int count = 1;
for(int i = 1; i < a.Count; i++){
    count += a[i-1] != a[i] ? 1 : 0;
}

还要记住,有一些持续不断的因素在起作用,可能会影响结果.例如,随机存储器访问比线性访问更昂贵,因为它使高速缓存更加困难.因此,在某些情况下,与更复杂的算法相比,更适合硬件的更简单的算法是首选的,并且一些实现根据数据集来切换策略.

Csharp相关问答推荐

我无法在Program.cs中实例化我的学生类

将.NET 8程序集加载到Matlab R2023a中时出现问题

在C#c/await中,延迟长度是否会影响控制返回调用者?

C#如何克服getter的接口空性

访问C#中的数据库字段时获取数据是收件箱错误-为什么?&有效,如果声明不有效

发布.NET框架项目将.NET核心元素注入到web. connect中

当Visual Studio处于升级管理模式时,无法安装Torch运行时

应该使用哪一个?"_counter += 1 OR互锁增量(ref_counter)"""

Entity Framework Core 8 dbcontext—无法以多对多关系添加某些行'

如何在Visual Studio代码中更改大括号模式{},用于C#语言

如果存在对CodeAnalysis.CSharp的引用,则不能引用netStandard2.0库

为什么总输出就像12.3没有一分一样?

Int和uint相乘得到LONG?

在命名管道上使用GRPC ASP.NET核心时如何配置命名管道权限

Cosmos SDK和Newtonsoft对静态只读记录的可能Mutations

依赖项注入、工厂方法和处置困境

在C#中过滤Excel文件

如何允许数组接受多个类型?

如何在C#中正确类型化带有泛型的嵌套类

未显示详细信息的弹出对话框