【问题标题】:Please suggest different approach for this CountNumbers algorithm请为此 CountNumbers 算法建议不同的方法
【发布时间】:2019-07-26 03:10:49
【问题描述】:

实现函数CountNumbers,它接受唯一整数的排序数组并计算小于参数lessThan的数组元素的数量

例如,SortedSearch.CountNumbers(new int[] { 1, 3, 5, 7 }, 4) 应该返回 2,因为有两个小于 4 的数组元素。

以下是我的方法。但是在线工具给出的分数是50%。我错过了什么?

using System;

public class SortedSearch
{
    public static int CountNumbers(int[] sortedArray, int lessThan)
    {
      int iRes=0;
        for (int i=0; i<sortedArray.Length; i++)
        {
            if(sortedArray[i]< lessThan)
            {
                iRes=iRes+1;
            }
        }
        return iRes;
    }

    public static void Main(string[] args)
    {
        Console.WriteLine(SortedSearch.CountNumbers(new int[] { 1, 3, 5, 7 }, 4));
    }
}

【问题讨论】:

标签: c# arrays


【解决方案1】:

您当前的解决方案最多 O(N) 其中N 是数组的大小。您可以利用输入数组已排序这一事实,通过使用BinarySearch 将解决方案的时间复杂度降低到:

public static int CountNumbers(int[] sortedArray, int lessThan)
{
    var result = Array.BinarySearch(sortedArray, lessThan);

    return result >= 0 ? result : -1 * result - 1;
}

为什么会有奇怪的-1 * result - 1 代码?因为,根据the docs

退货

指定值在指定数组中的索引,如果值为 成立;否则为负数。如果没有找到值并且值 小于数组中的一个或多个元素,负数 返回的是第一个元素的索引的按位补码 大于值。如果未找到值且值更大 比数组中的所有元素,返回的负数是 (最后一个元素的索引加 1)的按位补码。如果这 使用非排序数组调用方法,返回值可以是 不正确并且可能返回负数,即使值是 存在于数组中。

result - 1 反转“(最后一个元素的索引加 1)的按位补码”。

BinarySearch 通常会比WhereTakeWhile 执行得更快尤其是在处理大量数据时 - 因为它会执行binary search

来自wikipedia

在计算机科学中,二分查找,也称为半区间 搜索,对数搜索,或二分切,是一种搜索算法, 查找目标值在已排序数组中的位置。

使用二分搜索的线索是要求的“接受唯一整数的排序数组”部分。我的上述解决方案仅适用于已排序的唯一值数组。因此,在我看来,编写在线测试的人可能已经想到了二进制搜索。

【讨论】:

  • 没有意识到返回的负数是大于值的第一个元素的索引的按位补码。我以为它会是-1。感谢您指出这一点。这绝对是最好的答案。如果您可以引用未找到元素时计算负值的方式,那就太好了。
  • 那太好了@mjwills。得分为 100%。
【解决方案2】:

您可以为此目的使用 Linq。

int CountNumbers(IEnumerable<int> source,int limit)
{
    return source.TakeWhile(x=>x<limit).Count();
}

由于 OP 中已经提到输入数组已排序,因此当您发现第一个元素大于限制时,您可以退出搜索。 TakeWhile 方法同样可以帮助你。

上述方法,会在满足条件时选择所有元素,并找到项目的数量。

示例。

var result = CountNumbers(new int[] {1, 3, 5, 7},4);
Output : 2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2012-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多