排序搜索提高性能

时间:2017-09-23 05:40:56

标签: c# algorithm search

在testdome上进行练习...目前正在查看https://www.testdome.com/for-developers/solve-question/9877

  

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

     

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

我已进入:

public class SortedSearch
{
    public static int CountNumbers(int[] sortedArray, int lessThan)
    {
         int returnedValued = 0;

            foreach (int i in sortedArray)
            {
                if(i<lessThan)
                returnedValued += 1;
            }

            return returnedValued;
    }

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

我想知道为什么这个被标记为难度级难以及预期时间20分钟,当我知道它应该只需要几个。无论如何,4个案例中有2个通过。我没有超过时间限制,我猜我需要重构才能返回更快的搜索。这是正确的吗?如果是这样,任何人都可以帮忙吗?

      Example case: Correct answer 
      Various small arrays: Correct answer 
      Performance test when sortedArray contains lessThan: Time limit exceeded 
      Performance test when sortedArray doesn't contain lessThan: Time limit exceeded

3 个答案:

答案 0 :(得分:2)

他们希望您使用Array.BinarySearch方法获得100%。

using System;

public class SortedSearch
{
    public static int CountNumbers(int[] sortedArray, int lessThan)
    {
        if (sortedArray[0] >= lessThan) return 0;

        int lengthOfArray = sortedArray.Length;
        if (lengthOfArray == 0) return 0;
        if (sortedArray[lengthOfArray - 1] < lessThan) return lengthOfArray;

        int index = Array.BinarySearch(sortedArray, lessThan);
        if (index < 0)
            return ~index;

        return index;
    }

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

答案 1 :(得分:1)

你应该打破 foreach 循环,一旦,如果条件变为false,因为我们已经知道给定的数组已经排序,所以没有必要继续评估其他元素。请参阅以下代码段以供参考。

foreach (int i in sortedArray)
{
    if (i < lessThan)
        returnedValued += 1;
    else break;
}

请参阅下面通过所有4项测试的解决方案。我使用二分搜索技术找出大于 lessThan 变量的元素。

public static int CountNumbers(int[] sortedArray, int lessThan)
{
    //Handle all the corner cases
    int legthOfArray = sortedArray.Length;
    if (legthOfArray == 0) return 0;
    if (sortedArray[0] >= lessThan) return 0;
    if (sortedArray[legthOfArray - 1] < lessThan) return legthOfArray;
    return FindIndexGreaterOrEqualIndex(sortedArray, legthOfArray, lessThan, legthOfArray / 2);
}

public static int FindIndexGreaterOrEqualIndex(int[] sortedArray, int lengthOfArray, int lessThan, int currentIndex)
{
    while (true)
    {
        bool isCurrentElementLessThan = sortedArray[currentIndex] < lessThan;
        if (isCurrentElementLessThan) // Traverse Right hand side of binary tree.
            currentIndex = (int)Math.Ceiling((decimal)(currentIndex + lengthOfArray - 1) / 2);
        else if (sortedArray[currentIndex - 1] < lessThan && !isCurrentElementLessThan) //If array element is not less than and previous element is less than the given element. i.e. our answer so break the loop.
            break;
        else // Traverse Left hand side of binary tree.
            currentIndex = (int)Math.Ceiling((decimal)currentIndex / 2);
    }
    return currentIndex;
}

看一下:)

答案 2 :(得分:1)

这通过了所有4个测试:

public static int CountNumbers(int[] sortedArray, int lessThan)
{
    int val = Array.BinarySearch(sortedArray, lessThan);
    return val < 0 ? ~val : val;
}

正如其他人所说,他们希望您使用Array.BinarySearch,直到阅读第二条提示我才意识到。