假设我已将长度为n的数组A排序为1 我需要编写一个程序的pseuodocode,它给出每个元素的所有出现的输出 算法运行时必须是最大k(c1 + c2 * log(n))。
示例 - A = [1,1,2,2,2,5,5,5,5] ----> (1,2)(2,3)(5,4)
当我想要计算的第一个元素是A [1]并且我需要找到他最后一次出现时,我想到使用二分搜索。
然后下一个元素是A [最后出现的索引+ 1],依此类推。
我对这个想法有点困难并把它写成pseuodocode。
TNX
答案 0 :(得分:0)
递归算法,它得到左右位置并计算中间位置。如果有数字变化,那就更深入了。到目前为止,它是简单的二进制搜索。但是一旦它检测到(在距离= 1)边缘,数字的变化,它将以4个值返回它:'数字序列结束','在什么位置','什么开始','在什么位置'。父节点然后从左侧和右侧合并这4个值,如果它检测到“在中间”的完整序列,它会立即打印它并通过结束边缘(从左侧)和起始边缘(从右侧)。
答案 1 :(得分:0)
无法实现渐近复杂性。 原因是无论它是什么算法,当所有n个元素都是不同的时,它必须返回所有元素。这意味着它必须读取所有元素。当然,这个操作需要O(n)。
答案 2 :(得分:0)
您可以在O(log(n))
中计算一个条目的出现次数static int count(int[] array, int target, int start, int end, Func<int, int, bool> compare)
{
if (end < start) { return start; }
int m = (start + end) / 2;
if (compare(target, array[m])) { return count(array, target, start, m - 1, compare); }
else { return count(array, target, m + 1, end, compare); }
}
static void Main(string[] args)
{
int[] a = { 1, 3, 8, 12, 12, 12, 25, 88 };
int r1 = count(a, 12, 0, a.Length - 1, (x1, x2) =>
{
return x1 < x2;
});
int r2 = count(a, 12, 0, a.Length - 1, (x1, x2) =>
{
return x1 <= x2;
});
Console.Out.WriteLine("count=" + (r1 - r2).ToString());
}