问题
Running through exercises on testdome...currently looking at https://www.testdome.com/for-developers/solve-question/9877
Implement function
CountNumbers
that accepts a sorted array of integers and counts the number of array elements that are less than the parameterlessThan
.For example,
SortedSearch.CountNumbers(new int[] { 1, 3, 5, 7 }, 4)
should return 2 because there are two array elements less than 4.
I have entered:
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));
}
}
I was wondering why this was marked as difficulty level hard and expected time 20 min when I knew it should only take a few. Anyway, 2 out of 4 cases passed. I'm failing on time limit exceeded and I'm guessing I need to refactor to return a faster search. Is this right? And if so could anyone help with it?
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
回答1:
This passed all 4 tests:
public static int CountNumbers(int[] sortedArray, int lessThan)
{
int val = Array.BinarySearch(sortedArray, lessThan);
return val < 0 ? ~val : val;
}
As others have said, they expect you to use Array.BinarySearch which I didn't realise until read the 2nd hint.
回答2:
They expect you to use the Array.BinarySearch method to get 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));
}
}
回答3:
You should have to break the foreach loop, once if condition get false because we already know given array is sorted so there is no point to keep on evaluating further elements. Please see below code snippet for reference.
foreach (int i in sortedArray)
{
if (i < lessThan)
returnedValued += 1;
else break;
}
Please see below solution which passed all the 4 tests. I have used binary search technique to find out the element which is greater than lessThan variable.
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;
}
Have a look :)
来源:https://stackoverflow.com/questions/46376441/sorted-search-increase-performance