这是一个您可以尝试的解决方案。但是它假设了一些要点:
- 没有范围重叠
- 当您请求一个数字时,它实际上在一个范围内(无错误检查)
根据你的说法,这个是 O(N),但我认为你可以毫不费力地使其成为 O(log(N))。
这个想法是一个类将处理范围的事情,它基本上会将给它的任何值转换为其范围的下边界。这样,您的 Hashtable(此处为字典)包含低边界作为键。
public class Range
{
//We store all the ranges we have
private static List<int> ranges = new List<int>();
public int value { get; set; }
public static void CreateRange(int RangeStart, int RangeStop)
{
ranges.Add(RangeStart);
ranges.Sort();
}
public Range(int value)
{
int previous = ranges[0];
//Here we will find the range and give it the low boundary
//This is a very simple foreach loop but you can make it better
foreach (int item in ranges)
{
if (item > value)
{
break;
}
previous = item;
}
this.value = previous;
}
public override int GetHashCode()
{
return value;
}
}
这是测试它。
class Program
{
static void Main(string[] args)
{
Dictionary<int, int> myRangedDic = new Dictionary<int,int>();
Range.CreateRange(10, 20);
Range.CreateRange(50, 100);
myRangedDic.Add(new Range(15).value, 1000);
myRangedDic.Add(new Range(75).value, 5000);
Console.WriteLine("searching for 16 : {0}", myRangedDic[new Range(16).value].ToString());
Console.WriteLine("searching for 64 : {0}", myRangedDic[new Range(64).value].ToString());
Console.ReadLine();
}
}
我不相信您真的可以低于 O(Log(N)),因为您无法立即知道数字在哪个范围内,您必须始终将其与下限(或上限)进行比较.
如果您有预先确定的范围,那会更容易做到。也就是说,如果你的范围是每百个,那么通过计算任何数字的模 100 很容易找到正确的范围,但在这里我们不能假设任何内容,所以我们必须检查。
要使用此解决方案下降到 Log(N),只需将 foreach 替换为将查看数组中间的循环,然后每次迭代将其拆分为两个...