笔试算法模拟题精解之“完美排列”

简介: 本文通过两种解法描述86题“完美排列”的解题过程,更有对应的时间和空间复杂度帮助理解。

【在线编程产品介绍】

阿里云开发者社区在线编程:

免费刷题大神器,助你拿到好offer

周赛月赛不停歇,做题还能领奖品

大赛笔试全真题,常做常新有惊喜

点击链接开始产品体验:https://developer.aliyun.com/coding

本文为大家介绍的是“86.完美排列”的解法探究。先来看一下题目内容:

题目描述

等级:容易
知识点:贪心
查看题目: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)

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

在线编程周赛、月赛火热进行中,更有限时答题活动,社区定制卫衣、双肩背包等你来拿~每天都有好礼相送~点击了解周赛详情:在线编程内测中,抢先周赛赢好礼!面试考试前,快来刷刷题!

APPbanner784-312.png

上一篇:笔试算法模拟题精解之“坏掉的时钟”
下一篇:笔试算法模拟题精解之“Bob的花束”的“模拟”解法

相关文章
|
3月前
|
算法
电子好书发您分享《超全算法笔试 模拟题精解合集》
电子好书发您分享《超全算法笔试 模拟题精解合集》
25 3
|
3月前
|
算法
电子好书发您分享《超全算法笔试 模拟题精解合集》
电子好书发您分享《超全算法笔试 模拟题精解合集》
26 2
|
4月前
|
算法
算法编程(二十八):重新排列单词间的空格
算法编程(二十八):重新排列单词间的空格
35 0
|
6月前
|
算法 测试技术 C++
C++二分算法习题:判断是否是完全平方数[容易]和排列箱子[容易]
C++二分算法习题:判断是否是完全平方数[容易]和排列箱子[容易]
|
7月前
|
算法 Java
【Java每日一题,字典序算法】下一个排列
【Java每日一题,字典序算法】下一个排列
|
2月前
|
编解码 算法 前端开发
往年 | 大疆雷达算法校招笔试题目解析
往年 | 大疆雷达算法校招笔试题目解析
28 1
|
5月前
|
算法
压缩算法 【腾讯2020校园招聘-后台&综合-第一次笔试 】
压缩算法 【腾讯2020校园招聘-后台&综合-第一次笔试 】
29 0
|
6月前
|
算法
【每日挠头算法题(8)】最后一个单词的长度|重新排列字符串
【每日挠头算法题(8)】最后一个单词的长度|重新排列字符串
|
6月前
|
机器学习/深度学习 算法 测试技术
C++前缀和算法的应用:DI序列的有效排列的原理、源码及测试用例
C++前缀和算法的应用:DI序列的有效排列的原理、源码及测试用例
|
6月前
|
算法 C++
剑指offer(C++)-JZ38:字符串的排列(算法-搜索算法)
剑指offer(C++)-JZ38:字符串的排列(算法-搜索算法)