问题从Finding a single number in a list
延伸如果我将问题扩展到此: 查找在列表中只出现一次的数字的最佳算法是什么?所有其他数字恰好出现k次?
有没有人有好的答案?
例如,A = {1,2,3,4,2,3,1,2,1,3},在这种情况下,k = 3.如何在O中获得单个数字“4” (n)时间和空间复杂度是O(1)?
答案 0 :(得分:4)
如果数组中的每个元素都小于n且大于0
让数组为a,遍历每个a[i]
添加n
到a[(a[i])%(n)]
的数组。
现在再次遍历数组,a[i]
小于2*n
且大于n
的位置(假设基于1的索引)就是答案。
如果至少on元素大于n,则此方法不起作用。在这种情况下,你必须使用Jayram建议的方法
编辑:
要检索数组,只需将mod n
应用于数组中的每个元素
答案 1 :(得分:2)
如果lonely number
以外的数字正在偶数计数(即2,4,6,8 ......)中进行XOR
操作,则可以通过约束来解决这个问题在所有数字上。
但除了空间复杂性O(1)
之外,它只是在戏弄我。
如果不是您给定的约束,您可以使用这些方法来解决这个问题。
答案 2 :(得分:0)
我只想延长@banarun的答案。
将输入作为地图。像a[0]=1
;然后将其设为myMap
,其中0
为索引,1
为值。
在读取输入时找到最大数量M.然后找到大于A
的{{1}}素数为P。
如果M
未启动i
,则不会遍历地图并且myMap
P
的每个键myMap(myMap(i)%P)
添加myMap(myMap(i)%P)
将其设置为{{1} }}。现在再次遍历P
,myMap
和myMap[i] is >=P
的答案位置。基本上,理念是从banarun建议的Algo中删除溢出和覆盖问题。
答案 3 :(得分:0)
根据banarun解决方案(使用小修补程序):
算法条件:
for each i arr[i]<N (size of array)
for each i arr[i]>=0 (positive)
算法:
int[] arr = { 1, 2, 3, 4, 2, 3, 1, 2, 1, 3 };
for (int i = 0; i < arr.Length; i++)
{
arr[(arr[i])%(arr.Length)] += arr.Length;
if(arr[i] < arr.Length)
arr[i] = -1;
}
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] - 3 * arr.Length <0 && arr[i]!=-1)
Console.WriteLine("single number = "+i);
}
此解决方案的时间复杂度为O(N),空间复杂度为O(1)
注意: 同样,只有当所有数字都是正数并且所有数字都小于N时,此算法才能工作。
答案 4 :(得分:0)
这是一种机制,它可能不如其他机制那么好,但它具有指导性,并且解决了为什么XOR答案与k = 2时一样好的原因。
1. Represent each number in base k. Support there are at most r digits in the representation
2. Add each of the numbers in the right-most ('r'th) digit mod k, then 'r - 1'st digit (mod k) and so on
3. The final representation of r digits that you have is the answer.
例如,如果数组是
A = {1, 2, 3, 4, 2, 3, 1, 2, 1, 3, 5, 4, 4}
mod 3中的表示是
A = {01, 02, 10, 11, 02, 10, 01, 02, 01, 10, 12, 11, 11}
r = 2
Sum of 'r'th place = 2
Sum of the 'r-1'th place = 1
因此answer = {12} in base 3
即5
。
这是一个O(n * r)
的答案。请注意,r
与log n
成比例。
为什么O(n)
中的XOR答案?因为处理器提供的异或操作在O(1)
时间内执行,而不是我们上面的O(r)
因子。