我在接受采访时被问到这个问题.
鉴于此,有3n + 1个数字.这些数字中的n个出现在三元组中,只有1个出现在单个时间内.我们如何在线性时间内找到唯一的数字,即O(n)?这些数字没有排序.
请注意,如果有2n + 1个数字,其中n个成对出现,我们可以对所有数字进行异或,以找到唯一的数字.面试官告诉我,这可以通过比特操纵来完成.
您可以发明一个3nary XOR(调用它XOR3)操作,它在base 3而不是base 2中运行,并且简单地将每个3nary数字模3(当通常XOR采用2nary digit modulo 2时).
然后,如果您使用XOR3所有数字(首先将它们转换为3nary),您将获得唯一的数字(在基数3中,因此您需要将其转换回来).
然而,复杂性并不完全是线性的,因为从/到基数3的转换需要额外的对数时间.但是,如果数字范围是常数,则转换时间也是恒定的.
关于C++的代码(故意冗长):
vector<int> to_base3(int num) {
vector<int> base3;
for (; num > 0; num /= 3) {
base3.push_back(num % 3);
}
return base3;
}
int from_base3(const vector<int> &base3) {
int num = 0;
for (int i = 0, three = 1; i < base3.size(); ++i, three *= 3) {
num += base3[i] * three;
}
return num;
}
int find_unique(const vector<int> &a) {
vector<int> unique_base3(20, 0); // up to 3^20
for (int num : a) {
vector<int> num_base3 = to_base3(num);
for (int i = 0; i < num_base3.size(); ++i) {
unique_base3[i] = (unique_base3[i] + num_base3[i]) % 3;
}
}
int unique_num = from_base3(unique_base3);
return unique_num;
}
int main() {
vector<int> rands { 1287318, 172381, 5144, 566546, 7123 };
vector<int> a;
for (int r : rands) {
for (int i = 0; i < 3; ++i) {
a.push_back(r);
}
}
a.push_back(13371337); // unique number
random_shuffle(a.begin(), a.end());
int unique_num = find_unique(a);
cout << unique_num << endl;
}
Run Code Online (Sandbox Code Playgroud)