给定一个非顺序和无序数字的列表是否有一个索引列表的最佳方法,其中索引中的第i个元素是索引列表中第i个元素的位置(如果已排序)。
所以[45,2,6,33]会有索引[4,1,2,3]
答案 0 :(得分:0)
您可以对列表进行排序,然后创建一个字典/关联数组,将每个元素映射到排序列表中的索引。您可以在循环中执行此操作,或者在Python中,甚至可以在一行中执行此操作:
>>> lst = [45, 2, 6, 33]
>>> d = {x: i for (i, x) in enumerate(sorted(lst))}
>>> d
{2: 0, 6: 1, 33: 2, 45: 3}
现在使用字典中的值来创建结果列表:
>>> [d[x] + 1 for x in lst]
[4, 1, 2, 3]
如果列表中包含重复的数字,并且您不希望结果列表包含重复索引,则可以将值映射到索引列表:
>>> lst = [45, 2, 6, 33, 6]
>>> d = {}
>>> for i, x in enumerate(sorted(lst)):
... d.setdefault(x, []).append(i)
>>> d
{2: [0], 6: [1, 2], 33: [3], 45: [4]}
现在,将每个列表转换为迭代器,并为原始列表中的每个值获取下一个索引。
>>> d2 = {x: iter(d[x]) for x in d}
>>> [next(d2[x]) + 1 for x in lst]
[5, 1, 2, 4, 3]
答案 1 :(得分:0)
您可以执行基数排序,它使用计数排序作为子例程,并且对于大数字也可以在线性时间复杂度中工作。时间复杂度为O(n)
。
然后使用散列映射<element, position when sorted>
来记录排序列表中元素的位置。最后打印输入的相应位置。空间复杂度为O(n)
。
答案 2 :(得分:0)
您面临的问题似乎是如何在排序位置后保留元素的原始位置将会丢失。您需要将原始数组中的位置与元素链接,然后进行排序。以下是伪代码
list of pair p[] as (element, original position)
for each index i in original input array A
p.push(A[i], i) //adding element and original position
根据第一个元素排序
q = sort(p)
现在q在排序后的元素位置。第二个数组应该在原始数组的索引上有这个位置
让新数组B为结果数组
for each index i in array q
B[q[i].second] = i //q[i].second is index in original array. so putting index of sorted array in that
更新:有些人无法理解此算法,因此已将代码放入JavaScript中。
var input = [45,2,6,33];
var p = [];
for(var i = 0;i < input.length;i++)
{
p.push({first:input[i],second:i});
}
p.sort(function(a,b){
return a.first > b.first;
});
var B = Array(input.length);
for(var i = 0;i < p.length;i++)
{
B[p[i].second] = i;
}
console.log(B);