Algorithm 在3n+中查找唯一编号;1个数字
我在一次采访中被问到这个问题 因此,有3n+1个数字。这些数字中有n个出现在三胞胎中,只有1个一次出现。我们如何找到线性时间中的唯一数,即O(n)?数字没有排序Algorithm 在3n+中查找唯一编号;1个数字,algorithm,Algorithm,我在一次采访中被问到这个问题 因此,有3n+1个数字。这些数字中有n个出现在三胞胎中,只有1个一次出现。我们如何找到线性时间中的唯一数,即O(n)?数字没有排序 注意,如果有2n+1个数字,其中n个成对出现,我们可以对所有数字进行异或运算以找到唯一的数字。面试官告诉我,这可以通过位操作来完成。你可以发明一种3进制异或(称之为XOR3)运算,它在基3而不是基2上运行,只需取每个3进制数字模3(通常情况下,XOR取2进制数字模2) 然后,如果您以这种方式XOR3所有数字(首先将它们转换为3进制),您
注意,如果有2n+1个数字,其中n个成对出现,我们可以对所有数字进行异或运算以找到唯一的数字。面试官告诉我,这可以通过位操作来完成。你可以发明一种3进制异或(称之为
XOR3
)运算,它在基3而不是基2上运行,只需取每个3进制数字模3(通常情况下,XOR
取2进制数字模2)
然后,如果您以这种方式XOR3
所有数字(首先将它们转换为3进制),您将保留唯一的数字(在基数3中,因此需要将其转换回)
但复杂度并不是完全线性的,因为从/到基3的转换需要额外的对数时间。但是,如果数字的范围是恒定的,则转换时间也是恒定的
C++代码(有意冗长):
矢量到_base3(int num){
矢量基3;
对于(;num>0;num/=3){
base3.向后推_(数量%3);
}
返回基3;
}
来自_base3的int(常量向量和base3){
int num=0;
对于(int i=0,three=1;i计算每一位在3n+1数字集合中出现的次数
将每个位计数减少到模3
剩下的是单个数字的位模式
哦,dreamzor(上图)打败了我。byte[]oneCount=新字节[32];
byte [] oneCount = new byte [32];
int [] test = {1,2,3,1,5,2,9,9,3,1,2,3,9};
for (int n: test) {
for (int bit = 0; bit < 32; bit++) {
if (((n >> bit) & 1) == 1) {
oneCount[bit]++;
oneCount[bit] = (byte)(oneCount[bit] % 3);
}
}
}
int result = 0;
int x = 1;
for (int bit = 0; bit < 32; bit++) {
result += oneCount[bit] * x;
x = x << 1;
}
System.out.print(result);
int[]检验={1,2,3,1,5,2,9,9,3,1,2,3,9};
for(int n:测试){
用于(int位=0;位<32;位++){
如果((n>>位)&1)==1){
一计数[位]+;
oneCount[位]=(字节)(oneCount[位]%3);
}
}
}
int结果=0;
int x=1;
用于(int位=0;位<32;位++){
结果+=oneCount[位]*x;
x=x到目前为止你试过什么?你面试的目的是什么?关于记忆限制和数字的范围呢?为什么要转换成三元数?它比theorish的解决方案有什么额外的优势吗?@parvez_bai不,这只是我想到的第一个想法,因为与二进制/3元XOR的简单类比,他的解决方案确实更容易实现梅蒂。