查找小于或等于目标的数组中的最大数字

时间:2016-10-08 09:43:56

标签: c++ algorithm

这就是我在做的事情。 我有一个数组(或矢量),V然后我按升序排序。 小于或等于目标a的最高数字将位于i位置。(最初,i = 0

while (V[i] <= a && i < V.size()) { i++; }
 i--;

我在Codechef的一个问题中使用这部分代码,然后获得AC,但是早些时候我使用了这个并且错了。

while (V[i+1] <= a && i < V.size()-1) i++;

这两个人做的基本上不一样吗?为什么我会以第二而不是第一个获得WA?你能指出一个与它们不同的测试用例吗?

例如在测试用例中:

  

V = 5,7,10,12

     

a = 11

两者都以i = 2结尾。

我得到的另一个类似问题是:

我有另一个SORTED值列表说V2,我正在遍历。对于每个值x,我试图找到V中小于或等于x的最高数。这就是我之前做的事情:

while (V[i] <= x && i < V.size()) {
        i++;
    }
i--;

通过V2的每次迭代,我没有将i的值设置为0,而是从我之前的位置继续。 (因为V2已经分类)

所以,如果我有:

  

V = 5 7 10 12

     

V2 = 7 8 10 11 13

我的代码将返回索引1,1,2,2,3。即便如此,我还是得到了WA。 :/

但是当每次迭代通过V2之前我正在做i = 0时,我得到了AC。现在这很慢,这不是我最初想做的,但我不知道为什么当我没有将i重置为0时它不起作用。

帮助,伙计们? :3

编辑: 您可以在此处替换值。

vector <int> V1 = {1,2,3};
int target = 5;
int index = 0;
while (V1[index] <= target && index < V1.size()) { index++; }
index--;
cout << index << endl;
index = 0;
while (V1[index+1] <= target && index < V1.size()-1) index++;
cout << index << endl;

这似乎总是为每个提供的测试用例返回相同的答案。

1 个答案:

答案 0 :(得分:0)

由于要搜索的数组已经排序,您可以使用各种二进制搜索算法函数来查找正确的值。与您使用的搜索O(log n)相比,使用二进制搜索会O(n)复杂度来查找值。

换句话说,如果排序数组中有一百万个数字,那么逐个搜索以找到正确的值将需要最多一百万个比较。使用二进制搜索最多需要进行20次比较,其中比较仅在收缩序列的中间元素上进行(每次找不到数字时,序列都会减半)。

<algorithm>中,std::upper_bound可用于进行二分查找。诀窍是返回std::upper_bound返回的迭代器之前的值,并确保您不会超出值的下限以进行搜索。

#include <iostream>
#include <algorithm>

int getIndex(const std::vector<int>& V, int val)
{
    auto iter = std::upper_bound(V.begin(), V.end(), val);
    if ( iter != V.begin())
       // return the index of the item before the found item
       return std::distance(V.begin(), std::prev(iter));

    // return the first item
    return 0;
}

int main()
{
   std::vector<int> V = {5,7,10,12};
   std::vector<int> V2 = {7, 8, 10, 11, 13};
   std::for_each(V2.begin(), V2.end(), [&](int val)
   {std::cout << getIndex(V, val) << " ";});
}

See Live Example

请注意,该示例不会检查要查找的值是否小于向量中的任何值。您需要添加此检查并返回表示数字超出范围的值。