我有一个清单{10,5,3,9,12}。我需要把它转换成像这样的{3,1,0,2,4}。我的意思是将0分配给最小值,将1分配给下一个最小值。
我的代码:
list = {2,3,10,5,1};
for (int i =list.Count-1; i >= 0 ; i--)
{
var maxNo = list.Max();
var smallIndex = list.IndexOf(maxNo);
list[smallIndex] = i * -1;
}
for (int i = 0; i < list.Count; i++)
{
list[i] = list[i] * -1;
}
// prints {1,2,4,3,0}
注意:列表仅包含正数。
以上代码是否正常。 需要帮助。
答案 0 :(得分:5)
基本上你只需要对列表进行排序。看看排序算法。
您可以构建另一个包含原始数字的列表,该数字与从0到列表长度的整数索引配对,如{{10,0}, {5,1}, {3,2}, {9,3}, {12,4}}
,使用您的编程语言的内置排序函数对此列表进行排序,然后提取整数索引
EDIT2:实际的实现可能意味着为sort
使用不同的比较函数:假设您的原始列表被称为array
。创建另一个数组idx = {0,1,2,3,4}
,并且不是基于比较函数x < y
而是array[x] < array[y]
对其进行排序。
<强> CORRECTION 强>
这里的算法找到了所需要的逆置换。正如唐提到的那样,你需要做另一种来颠倒排列。
答案 1 :(得分:3)
这是O(2 (n log n))
因为它排序两次。首先,它将列表转换为按(index, value)
排序的v
列表,并添加排序后的位置s
并按索引排序,然后提取排序后的位置。
>>> list( s for s, i in sorted( ( (s,i) for s,(i,v) in enumerate(sorted( ( (i,v) for i,v in enumerate([10,5,3,9,12]) ), key=lambda t: t[1] )) ), key=lambda t: t[1] ) )
[3, 1, 0, 2, 4]
或多行(请注意,这可能会使内存保留的时间超过所需时间):
def arrange(l):
a = sorted( ( (i,v) for i,v in enumerate(l) ), key=lambda t: t[1] )
b = sorted( ( (s,i) for s,(i,v) in enumerate(a) ), key=lambda t: t[1] )
return list( s for s, i in b )
print arrange([10,5,3,9,12])
答案 2 :(得分:2)
您的算法适用于非负整数列表,但正如其他人所说,由于重复的最大计算,它的效率不高。
我不确定我在这里增加多少,因为Dan D的答案是正确的,但也许更多的解释会有所帮助......
在{2,3,10,5,1}
映射到{1,2,4,3,0}
的示例中,您要查找的是原始列表在排序列表中占据的索引列表。
最自然的方法是通过排序,索引和“取消分类”如下(并且在Dan D的有点terser解决方案中实现):
为原始数据添加索引列:
{2,3,10,5,1} => {(2,0), (3,1), (10,2), (5,3), (1,4)}
按原始列排序:
{(2,0), (3,1), (10,2), (5,3), (1,4)} => {(1,4), (2,0), (3,1), (5,3), (10,2)}
添加另一个索引列:
{(1,4), (2,0), (3,1), (5,3), (10,2)} => {(1,4,0), (2,0,1), (3,1,2), (5,3,3), (10,2,4)}
通过对第一个索引列进行排序来回到原始订单:
{(1,4,0), (2,0,1), (3,1,2), (5,3,3), (10,2,4)} => {(2,0,1), (3,1,2), (10,2,4), (5,3,3), (1,4,0)}
删除原始列和第一个索引列,只保留在中间添加的索引,该索引现已放到正确的位置:
{(2,0,1), (3,1,2), (10,2,4), (5,3,3), (1,4,0)} => {1,2,4,3,0}
无论原始列表的数据类型如何,只要可以对其进行排序,此策略就可以正常工作。
由于问题肯定涉及一些排序,我强烈怀疑你可以做得比这更好的效率。添加和删除列是线性的,排序两次并不比排序一次差。
答案 3 :(得分:1)
这样可行,但每个项目使用list.IndexOf(maxNo)
一次会产生O(n ^ 2)的时间。排序列表会更有效,除了维护一个索引数组,使得ix [i]是第i个最大项。换句话说,比较list [i],但在排序中分配ix [i]。这也适用于负数。
答案 4 :(得分:0)
对列表的副本进行排序,将其放入带有列表项作为键的键控数据结构中,并将排序列表中的位置作为值。使用键控数据结构映射原始列表。 knlogn + 2n = O(nlogn)表现。