The challenge requires the program to receive data from the console and use binary search to find if a term is contained in a set of other terms. I've unit-tested the solution below, but according to the grader, my solution is too slow (i.e. the logic is "correct" but inefficient). The grader returns 30 seconds of execution time presumably for very large input (which I can't access).
Where's the bottleneck (or, how can I make this faster?)
The input consists of two lines:
- Input line 1 contains the number of data, followed by the actual data, already sorted.
Example:5 1 5 8 12 13
represents a five-element list1 5 8 12 13
. - Input line 2 contains the number of search terms, followed by the search terms.
Example:5 8 1 23 1 11
represents five search terms: 8, 1, 23, 1, 11. - Output for the example above:
2 0 -1 0 -1
Explanation: search term 8 is found at actual data location 2, 1 is found at 0, 23 is not found (returns -1), 1 is found at 0, 11 is not found (-1)
using System;
using System.Collections.Generic;
using System.Linq;
namespace BinarySearch
{
public class Program
{
public static void Main(string[] args)
{
new Launcher().Run(args);
}
}
public class Launcher
{
public void Run(string[] args)
{
var input = Console.ReadLine().Split(' ').Select(n => Convert.ToInt64(n)).ToArray();
var numData = (int)input[0];
// attempt to make console reading faster...
//var data = input.Skip(1).Take((int) (numData)).ToArray();
// attempt to make console reading faster...
//var data = new ArraySegment<long>(input, 1, numData).ToArray();
var data = new List<long>(input).GetRange(1, numData).ToArray();
var searchTerms = Console.ReadLine().Split(' ').Select(n => Convert.ToInt64(n)).ToArray();
var numSearchTerms = (int)searchTerms[0];
// attempt to make console reading faster...
//var search = searchTerms.Skip(1).Take((int)(numSearchTerms)).ToArray();
// attempt to make console reading faster...
//var search = new ArraySegment<long>(searchTerms, 1, numSearchTerms).ToArray();
var search = new List<long>(searchTerms).GetRange(1, numSearchTerms).ToArray();
Console.WriteLine(BinarySearchSetup(data, search));
}
public string BinarySearchSetup(long[] data, long[] searchTerms)
{
var resultString = "";
var lowerBound = 0;
var upperBound = data.Length - 1;
for (var i = 0; i < searchTerms.Length; i++)
resultString += BinarySearch(data, lowerBound, upperBound, searchTerms[i]) + " ";
return resultString.Trim();
}
public long BinarySearch(long[] data, long low, long high, long key)
{
if (high < low)
return -1;
var mid = low + (high - low) / 2;
if (key == data[mid])
return mid;
else if (key < data[mid])
return BinarySearch(data, low, mid - 1, key);
else
return BinarySearch(data, mid + 1, high, key);
}
}
}