如何解决对数组进行排序的算法,其中每个元素都与它应该在的位置相距 10 个位置
对具有 n 个元素且 EVERY 元素在排序后与它的位置原先相距 10 个位置的数组进行排序的最有效排序算法是什么?
我正在考虑插入排序,但我不知道如何证明:
(1) 效率最高。
(2) 算法在最坏情况下需要 O(n) 步来对数组进行排序。
一个自我设想的例子:[10,11,12,13,14,15,16,17,18,19,1,2,3,4,5,6,7,8,9,]
解决方法
有了这些限制,可能性就不多了:
索引 0 处的值必须移动到索引 10,因为这是唯一一个距离索引 0 10 个位置的索引。哪个值可以移动到索引 0?它只能是当前位于索引 10 的值。所以它是索引 0 和 10 之间的交换。
同理,索引 1 处的值将与索引 11 处的值交换,2 与 12 交换,3 与 13 交换,... 9 与 19 交换。
所以现在我们已经涵盖了 0..19 范围内的所有索引。此范围之外的任何值都不会进入此范围,此范围内的任何值也不会移出该范围。上面已经定义了所有涉及这些指数的运动。
我们可以对 20..39 范围内的索引重复相同的推理,再次从位置 40..59,...等
所以我们可以得出结论:
- 数组的大小必须是 20 的倍数
- 只有一种排列可能符合给定规则
- 因此解决方案很简单。
伪代码解决方案:
sort(A):
for i = 0 to size(A) - 1 step 20:
swap A[i+0..i+9] with A[i+10..i+19]
在某些语言中,这种数组切片的交换可以非常有效地完成。
,当您说距离 10 个位置时,实际位置可能是 i - 10
或 i + 10
。
因此,只需制作一个数组的临时副本,并为每 10 个索引位置取最小值。
这是因为我们可以假设的唯一冲突是某个索引指向 +10
,另一个索引指向 -10
,用于 some 相同索引 j
。因此,取最小值将在索引 j
处安装正确的值。
private static void solve(int[] arr){
int[] temp = new int[arr.length];
Arrays.fill(temp,Integer.MAX_VALUE);
for(int i=0;i<arr.length;++i){
if(i - 10 >= 0) temp[i - 10] = Math.min(temp[i - 10],arr[i]);
if(i + 10 < temp.length) temp[i + 10] = Math.min(temp[i + 10],arr[i]);
}
for(int i=0;i<arr.length;++i) arr[i] = temp[i];
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。