让我们说这对值是:5和10
并且
范围R的数组是: R = {(6,10),(5,7),(6,9),(4,12)}
在这种情况下,它应该返回True
因为5和10位于4到12之间。
在O(N)
中显然有一个非常简单的解决方案,通过迭代每一对,可以通过根据R中的一对值的第一个值对范围R进行排序来进一步改进(尽管我猜是排序)会造成最坏情况O(n log n))。但问题是当我需要找到多对值的答案时。我正在寻找一个更好的解决方案,可能在某种程度上使用map
,这减少了重新计算某些值的需要。基本上,是否有使用动态编程的方法?
有什么想法吗?不过代码也会受到赞赏:P
答案 0 :(得分:0)
如果您想使用地图,一种解决方案是创建地图地图,一个用于最小值,一个用于最大值。这将需要一些预处理时间,但总体来说它会更快,因为长期运行并且需要进行多次查找。
您基本上创建了一个地图,其中包含每个有效最小值的键,并且每个值内部都有一个地图,其中包含该最大值的每个有效最大值的键。
例如(注意,未经测试的信封背面代码!):
// Psuedo-ish C++11
typedef std::map<int, std::vector<R>> MaxMap;
typedef std::map<int, MaxMap> MinMap;
MinMap minMap;
// Build maps
for(range : R)
{
for(int i=range.min; i<=range.max; ++i)
{
MaxMap& maxMap = minMap[i];
for(int j=range.min; j<=range.max; ++j)
{
// We just need some value in the map,
// so might as well store a list of the original ranges..
mapMap[j].push_back(range);
}
}
}
然后,对于查找,您可以获取最小值并在MinMap中查找,然后在MaxMap中查找最大值。请记住,MinMap为您提供了任何给定最小值的所有有效最大值,然后您在MaxMap中的查找会告诉您最大值是否为给定最小值的有效最大值...
bool isValidRange(int min, int max)
{
MinMap::iterator minIt = minMap.find(min);
if(minIt == minMap.end())
{
return false;
}
MaxMap& maxMap = minIt->second;
MaxMap::iterator maxIt = maxMap.find(max);
if(maxIt == maxMap.end())
{
return false;
}
return true;
}
当然,这只适用于自然数。如果你的范围内需要负数或实数,你还需要别的东西......