我们称一个长度为n的序列为正则序列,当且仅当该序列是一个由1~n组成的排列,即该序列由n个正整数组成,取值在[1,n]范围,且不存在重复的数,同时正则序列不要求排序 有一天小团得到了一个长度为n的任意序列s,他需要在有限次操作内,将这个序列变成一个正则序列,每次操作他可以任选序列中的一个数字,并将该数字加一或者减一。 请问他最少用多少次操作可以把这个序列变成正则序列? 数据范围: 1≤ n ≤ 20000 , 0≤ abs(s_i) ≤ 10000 进阶:时间复杂度 O(n) ,空间复杂度 O(n)
输入第一行仅包含一个正整数n,表示任意序列的长度。(1输入第二行包含n个整数,表示给出的序列,每个数的绝对值都小于10000。
输出仅包含一个整数,表示最少的操作数量。
5 -1 2 3 10 100
103
考点:贪心
数据规模 n ≤ 20000 | 限制 1 秒 / 256MB | 标准输入输出
推荐方向:贪心
本题切入点
把序列升序排序后,把第 i 小的数对齐到 i,代价就是 |s[i]−i| 之和——排序后按位配对即最优。
每一步都取当前最优,靠问题性质保证局部最优能拼成全局最优。
思路框架(贪心 通法 · 非本题专属)
实现要点:贪心题关键在于排序规则:按什么关键字排序决定了策略是否正确。
复杂度:时间 O(n log n)(含排序) | 空间 O(1) ~ O(n)
该范式的通法易错点
对照本题
样例 1
5 / -1 2 3 10 100103解析由校招宝本地引擎整理(依据源站考点标签 / 人工判题标注 / 题面规模信号),非官方题解,仅供思路参考。
本题来源:美团2023校招笔试第10场编程题。