检查一对值是否位于范围数组的范围之间

时间:2016-10-03 15:42:38

标签: c++ algorithm dictionary dynamic-programming

  

让我们说这对值是: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

1 个答案:

答案 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;
}

当然,这只适用于自然数。如果你的范围内需要负数或实数,你还需要别的东西......