注意,这是一项家庭作业。
我需要找到数组的模式(正值),如果模式大于sizeof(array)/2
(主导值),则返回该值。有些阵列没有。
这很简单,但是有一个限制,在确定之前不能对数组进行排序,此外,复杂性必须在O(nlogn)的数量级上。
使用这个第二个约束和master theorem,我们可以确定时间复杂度'T(n)= A * T(n / B)+ n ^ D',其中A = B和log_B(A) = D表示O(nlogn)为真。因此,A = B = D = 2。这也很方便,因为主导值必须在阵列的第一,第二或两半中占主导地位。
使用'T(n)= A * T(n / B)+ n ^ D'我们知道搜索函数会在每个级别调用自己两次(A),将每个级别设置的问题除以2( B)。我不知道如何让我的算法考虑到每个级别的n ^ 2。
制作一些代码:
int search(a,b) {
search(a, a+(b-a)/2);
search(a+(b-a)/2+1, b);
}
我在这里缺少的“胶水”是如何组合这些分开的功能,我认为这将实现n ^ 2的复杂性。这里有一些技巧,其中主导必须在第一或第二半中占主导地位,或两者兼而有之,不太确定这对于我现在如何通过复杂性约束来帮助我。
我已经写下了一些小数组的例子,并且我已经提出了它可以划分的方法。我似乎无法找到一个始终返回主导价值的单一方法。
在级别0,函数需要调用自身来搜索数组的前半部分和后半部分。这需要递归,并自行调用。然后在每个级别,它需要执行n ^ 2个操作。因此,在数组[2,0,2,0,2]中,它会将其拆分为[2,0]上的搜索和[2,0,2]上的搜索并执行25次操作。搜索[2,0]将调用[2]上的搜索并搜索[0]并执行4次操作。我假设这些需要搜索数组空间本身。我打算使用C ++并使用STL中的东西来迭代和计算值。我可以创建一个大型数组,只需按索引更新计数。
答案 0 :(得分:2)
如果你想找到一个数组的主导模式,并递归地执行,这里是伪代码:
def DominantMode(array):
# if there is only one element, that's the dominant mode
if len(array) == 1: return array[0]
# otherwise, find the dominant mode of the left and right halves
left = DominantMode(array[0:len(array)/2])
right = DominantMode(array[len(array)/2:len(array)])
# if both sides have the same dominant mode, the whole array has that mode
if left == right: return left
# otherwise, we have to scan the whole array to determine which one wins
leftCount = sum(element == left for element in array)
rightCount = sum(element == right for element in array)
if leftCount > len(array) / 2: return left
if rightCount > len(array) / 2: return right
# if neither wins, just return None
return None
上述算法是O(nlogn)时间,但只有O(logn)空间。
如果要查找数组的模式(不仅仅是主导模式),首先要计算直方图。您可以在O(n)时间内完成此操作(通过将数组值映射到其频率的哈希表中存储历史记录,只需访问数组的每个元素一次)。
计算完直方图后,您可以迭代它(最多访问每个元素一次)以找到最高频率。一旦发现频率大于数组大小的一半,就可以立即返回并忽略直方图的其余部分。由于直方图的大小不能大于原始数组的大小,因此该步骤也是O(n)时间(和O(n)空间)。
由于两个步都是O(n)时间,因此算法复杂度为O(n)时间。
答案 1 :(得分:2)
如果某个数字超过一半,可以通过O(n)时间复杂度和O(1)空间复杂度来完成,如下所示:
int num = a[0], occ = 1;
for (int i=1; i<n; i++) {
if (a[i] == num) occ++;
else {
occ--;
if (occ < 0) {
num = a[i];
occ = 1;
}
}
}
因为你不确定是否会出现这样的数字,所以你需要做的就是先应用上面的算法得到一个数字,然后第二次迭代整个数组得到数字的出现并检查它是否大于一半。