给定n=1e5的数组,每个元素是[-1e9, 1e9]。
一次操作为: 将一个元素的值 修改为 任意值。
问最少几次操作,可以使得 数组是《连续递增》
所谓《连续递增》是: 将该数组sort后,数组是一个 公差为1 的等差数组。
比如: [6, 5, 2, 3, 4]
这就是《连续递增》的。因为他sort后是:[2, 3, 4, 5, 6]
[4, 3, 2, 6, 6]
-> [4, 3, 2, 5,6]
。 答案是1.
[1, 10, 100, 1000]
-> [1, 2, 3, 4]
。 答案是1
令n为数组长度, 假设最终的 合法数组是: [l, l+1, ..., l+n-1]
(不唯一)
- 1,这n个数里,至少有1个 是等于 原来数组A[]里的某个元素。
即,至少有1个元素 是不用修改的。(这个性质很显然) - 2,这个
[l]
,一定可以是 原来数组A[]里的某个元素。 (这点很重要!!需要证明)
假设不是,因为1性质,设最小的 不用修改的元素是:[l + x]
(即,该元素 在原数组和最终数组,值相同,不用修改)
因为[l] [l+1] ... [l+x-1]
,这些元素 都是修改过的。我们可以将他们,修改到:[l+n] [l+n+1]...
,这样,依然满足是 递增的。
此时, 当前的[l + x]
,就成了 该数组中的 最小值,而且他是 未修改的。
即,原数组A 里的某个元素,一定可以不修改,而且是 最终数组的最小值。
令delta = n - 1
,最终数组是: [lef, ..., lef + delta]
因此,遍历每一个元素cur = A[i]
,判断,[cur + 1, .., cur + delta]
这个区间里 有多少个数,是等于原数组里的数。
比如:[1, 2, 2, 3] delta = 4 - 1 = 3
cur = 1时, 他对应的数组是:[1,2,3,4]。 而[2,3,4]中,2和3是原数组已存在的。
所以,1
对应的答案是: 1(因为没有4,需要某个元素修改为4)
需求: 给定区间[cur + 1, cur + delta]
,问这delta个数,有多少个数 是等于原数组的。
在原数组A中,找第一个>= (cur + 1)
的元素,再找最后一个 <= (cur + delta)
的元素
当然,需要满足: A是有序的,且A是去重的。
比如数组A是:[1, 3, 5, 6]
, 给定区间是:[3, 4, 5, 6]
二分会得到[3] 和 [6],对应3个元素
,即 可以匹配3个元素。
int minOperations(vector<int>& A) {
int n