Algorithm 在线性时间内排序[log n]不同的值
我有一个由n个整数组成的数组,它只能假设logn个可能值和任意值。例如,在S=[349,12,12283349283283,12]中,只有3个不同的数字log8=3 我必须在不到Onlogn的时间内对这个数组进行排序。我应该使用哪种算法?可能是基数排序和计数排序?它的分析如何?基数排序复杂度是Odn,d是数字中的位数 只有当d为常数时,该算法才能在线性时间内运行!在您的情况下,d=3logn,您的算法将在Onlogn中运行 老实说,我不知道如何在线性时间内解决这个问题。关于数字的性质还有其他信息吗我想知道关于数字的性质是否还有其他信息缺失 这是DNA的MSD基数排序的一个简单实现。它是用D写的,因为这是我用得最多的语言,因此我最不可能犯愚蠢的错误,但它可以很容易地翻译成其他语言。它已就位,但需要2*seq.length通过阵列Algorithm 在线性时间内排序[log n]不同的值,algorithm,sorting,radix-sort,Algorithm,Sorting,Radix Sort,我有一个由n个整数组成的数组,它只能假设logn个可能值和任意值。例如,在S=[349,12,12283349283283,12]中,只有3个不同的数字log8=3 我必须在不到Onlogn的时间内对这个数组进行排序。我应该使用哪种算法?可能是基数排序和计数排序?它的分析如何?基数排序复杂度是Odn,d是数字中的位数 只有当d为常数时,该算法才能在线性时间内运行!在您的情况下,d=3logn,您的算法将在Onlogn中运行 老实说,我不知道如何在线性时间内解决这个问题。关于数字的性质还有其他信息
void radixSort(string[] seqs, size_t base = 0) {
if(seqs.length == 0)
return;
size_t TPos = seqs.length, APos = 0;
size_t i = 0;
while(i < TPos) {
if(seqs[i][base] == 'A') {
swap(seqs[i], seqs[APos++]);
i++;
}
else if(seqs[i][base] == 'T') {
swap(seqs[i], seqs[--TPos]);
} else i++;
}
i = APos;
size_t CPos = APos;
while(i < TPos) {
if(seqs[i][base] == 'C') {
swap(seqs[i], seqs[CPos++]);
}
i++;
}
if(base < seqs[0].length - 1) {
radixSort(seqs[0..APos], base + 1);
radixSort(seqs[APos..CPos], base + 1);
radixSort(seqs[CPos..TPos], base + 1);
radixSort(seqs[TPos..seqs.length], base + 1);
}
}
按第一位数字排序产生
19, 25, 27, 22, 49, 47, 67, 87, 90, 91
接下来,按第二个数字排序,得到
90, 91, 22, 25, 27, 47, 67, 87, 19, 49
似乎不对,不是吗?或者这不是你正在做的吗?如果我弄错了,也许你可以给我们看看密码
如果您对所有具有相同第一位数字的组执行第二个bucket排序,那么您的算法将等同于递归版本。它也将是稳定的。唯一的区别是,你要做的是深度优先,而不是宽度优先
更新
检查此答案:基数排序复杂度是Odn,d是数字中的位数
只有当d为常数时,该算法才能在线性时间内运行!在您的情况下,d=3logn,您的算法将在Onlogn中运行
老实说,我不知道如何在线性时间内解决这个问题。关于数字的性质还有其他信息吗我想知道关于数字的性质是否还有其他信息缺失
这是DNA的MSD基数排序的一个简单实现。它是用D写的,因为这是我用得最多的语言,因此我最不可能犯愚蠢的错误,但它可以很容易地翻译成其他语言。它已就位,但需要2*seq.length通过阵列
void radixSort(string[] seqs, size_t base = 0) {
if(seqs.length == 0)
return;
size_t TPos = seqs.length, APos = 0;
size_t i = 0;
while(i < TPos) {
if(seqs[i][base] == 'A') {
swap(seqs[i], seqs[APos++]);
i++;
}
else if(seqs[i][base] == 'T') {
swap(seqs[i], seqs[--TPos]);
} else i++;
}
i = APos;
size_t CPos = APos;
while(i < TPos) {
if(seqs[i][base] == 'C') {
swap(seqs[i], seqs[CPos++]);
}
i++;
}
if(base < seqs[0].length - 1) {
radixSort(seqs[0..APos], base + 1);
radixSort(seqs[APos..CPos], base + 1);
radixSort(seqs[CPos..TPos], base + 1);
radixSort(seqs[TPos..seqs.length], base + 1);
}
}
按第一位数字排序产生
19, 25, 27, 22, 49, 47, 67, 87, 90, 91
接下来,按第二个数字排序,得到
90, 91, 22, 25, 27, 47, 67, 87, 19, 49
似乎不对,不是吗?或者这不是你正在做的吗?如果我弄错了,也许你可以给我们看看密码
如果您对所有具有相同第一位数字的组执行第二个bucket排序,那么您的算法将等同于递归版本。它也将是稳定的。唯一的区别是,你要做的是深度优先,而不是宽度优先
更新
检查此答案:由于只有logn唯一元素,因此可以使用以下算法及时获取排序列表: 创建列表中有多少不同项的映射,并将每个项的计数保留为键count的dictionary/hashmap 这是对输入列表的一次迭代,依此类推。 根据大小为logn的元组的键对上面的元组列表进行排序。 假设我们使用合并排序,那么合并排序的时间复杂度是k*logk,其中k是输入的大小。 用logn替换k,我们得到这个步骤的复杂性为Ologn*logn。 因为在复杂度方面,Ologn*loglogn
def duplicates_sort(xs):
keys = collections.Counter(xs)
result = []
for k in sorted(keys):
result.extend([k] * keys[k])
return result
使用哈希表time:On计算列表中每个元素的数量。
取消重复列表时间:On。
对现在已消除重复的项目进行排序时间:Olog n*log n。
建立一个列表,列出每个项目的正确份数时间:开。
总的来说,这是开放的,易于实现
下面是一些实现此功能的python:
def duplicates_sort(xs):
keys = collections.Counter(xs)
result = []
for k in sorted(keys):
result.extend([k] * keys[k])
return result