雲計算

Solution 86.完美排列

题目描述

完美排列的定义为一个长度为n的数组,n个元素各不相同且每个元素均在[1,n]的范围内。
现在给你长度为n的数组,你每次可以进行如下操作:任选数组中的一个元素,将其加一或者减一,问最少需要多少次操作才能够使得该数组为一个完美排列。

输入一个整数n,表示数组的长度(1 <= n <= 10^4);
再输入含有n个数的数组,第i个数表示数组中的第i个元素为ai(1 <= ai <= 10^5)。

输出一个整数表示将该数组变成一个完美排列的最少操作次数。
示例1
输入:
2
[3,0]
输出:
2
注意:
3->2
0->1
总共需要操作两次。









解法探究

解法一:正常贪心思路

本题是一道典型的贪心算法题,问题可以通过每步的最优策略分治解决。如果将 n 个大小未知的正整数,通过题目中的规则“填充”到槽 1~n 中,我们不妨从最小的数字槽 1 开始做起。

显然,这 n 个正整数中最小的数字 a(无论这个最小的数字是 1 或是 100),是填充槽 1 的最佳选择。其它(n-1)个数字和 1 的“距离”,都必定大于等于 a,距离槽 1 的距离都不如 a 更优,所以可以将 a 填充进槽 1,并在后续选择中排除掉它。

当填充槽 2 时,依旧用上面的思路就可以了。用剩下的(n-1)个数字中最小的数字去通过加减 1 进入槽 2,必定是填充槽 2 所有方式中的最佳策略。

将上面的思路重复应用,就得到了结果。复杂度上需要扫描 n 次数组。

时间复杂度:O(n^2)

空间复杂度:O(1)

解法二:排序优化

上面的反复扫描非常浪费时间,不如提前对数组排序,然后从排序后递增数组的第一项开始,逐个比较与槽 1~n 的距离,最后加到一起,得到答案。

时间复杂度:O(logn)

空间复杂度:O(1)

看完之后是不是有了答题思路了呢,快来练练手吧:查看题目:完美排列

周赛、月赛火热进行中,更有限时答题活动,每天都有好礼相送~欢迎钉钉扫码入群交流~

在线编程用户交流群二维码.png

Leave a Reply

Your email address will not be published. Required fields are marked *