除了“小尺寸向量”和“无重复”之外,如果您的键总是在一个小范围内(例如“没有键将永远大于 10.000 "),那么您可以利用这些额外信息来实现 O(max(N,M)) 解决方案(@Jarod 的解决方案是 O(max(N,M) * log(N+M)),@Adrian 的解决方案是 O(N *M))。
首先,建立一个足够大的素数(即一个大于最大键的素数),然后开始构建一个哈希图直到第一次发生冲突的点。
std::pair<size_t, size_t> findFirstMatch(const std::vector<int>& u, const std::vector<int>& v, const int& prime) {
std::vector<size_t> hashmap(prime, INT_MAX); // ---> 'INT_MAX' returned if no common entries found.
size_t smallerSz = std::min(u.size(), v.size());
std::pair<size_t, size_t> solution = { INT_MAX, INT_MAX };
bool noCollision = true;
// Alternate checking, to ensure minimal testing:
for (size_t i = 0; i < smallerSz; ++i) {
//One step for vetor u:
size_t& idx = hashmap[u[i] % prime];
if (idx < INT_MAX) { // ---> Collision!
solution = { i, idx };
noCollision = false;
break;
}
idx = i;
//One step for vector v:
idx = hashmap[v[i] % prime];
if (idx < INT_MAX) { // ---> Collision!
solution = { idx, i };
noCollision = false;
break;
}
idx = i;
}
//If no collisions so far, then the remainder of the larger vector must still be checked:
if(noCollision){
bool uLarger = u.size() > v.size();
const std::vector<int>& largerVec = (uLarger) ? u : v;
for (size_t i = smallerSz; i < largerVec.size(); ++i) {
size_t& idx = hashmap[largerVec[i] % prime];
if (idx < INT_MAX) { // ---> Collision!
if (uLarger) solution = { i, idx };
else solution = { idx, i };
break;
}
idx = i;
}
}
return solution;
}
用法
int main()
{
std::vector<int> u = { 32, 25, 13, 42, 55, 33 }, v = { 18, 72, 53, 39, 13, 12, 28 };
const int prime = 211; // ---> Some suitable prime...
std::pair<size_t, size_t> S = findFirstMatch(u, v, prime);
std::cout << "Solution = {" << S.first << "," << S.second << "}." << std::endl;
return 0;
}
它输出“{2, 4}”而不是“{3, 5}”,因为第一个索引是 0。随意修改它。