Categorygithub.com/szhou12/leetcode-goleetcode2009-Minimum-Number-of-Operations-to-Make-Array-Continuous
package
0.0.0-20241220224003-b7cf03a90b2b
Repository: https://github.com/szhou12/leetcode-go.git
Documentation: pkg.go.dev
# README
2009. Minimum Number of Operations to Make Array Continuous
Solution idea
Sliding Window - 窗口长度可变
-
预处理:
nums
需要先去重- 为什么需要去重复? 因为每多一个重复元素,我们需要把它变大使得数组整体变得连续, 如果不连续的话,双指针的代码部分会把重复的元素都当成不需要变换的元素 (
min(N-(right-left))
),这样显然是不对的
- 为什么需要去重复? 因为每多一个重复元素,我们需要把它变大使得数组整体变得连续, 如果不连续的话,双指针的代码部分会把重复的元素都当成不需要变换的元素 (
- 去重后,需要从小到大排列
-
左边界: 一定是某个
arr[left]
- i.e. 对于最优解而言,连续区间的左端点一定是落在
arr
的某一个数值上
- i.e. 对于最优解而言,连续区间的左端点一定是落在
-
右边界延伸的条件:
arr[right]-arr[left]+1 <= len(nums)
- meaning: 数轴上的连续区间
arr[left...right]
的跨度大于len(nums)
, 说明把nums
所有元素都往里填充都填不满这个区间了, 就说明,right
跑的太远了,left
需要收缩了. - 也就是说,是否
arr[right]-arr[left]+1 <= len(nums)
? 是的话,那么这个数值区间arr[left...right]
一定能被nums
的元素 填满,nums
也有可能还有多余的元素,我们就将它们继续拼接在区间的右边即可。这样,对于固定的left
,我们能找到最大的right
,使得这个区间尽量地大,那么需要从外面拿进来填充的nums
元素自然就会尽量的少了。 - e.g.
arr[left]=1, arr[right]=6
, 那么 数轴上的连续区间arr[left...right] = [1,2,3,4,5,6]
. 如果nums=[1,2,3,5,6]
, 显然,right
走的太远了 (多出了 用光nums
所有元素 都填不满的空位), 因为nums
只需要把 6 变成 4 得到[1,2,3,4,5]
, 所以 数轴上的连续区间arr[left...right] = [1,2,3,4,5]
就可以
- meaning: 数轴上的连续区间
-
需要变换的元素个数:
len(nums) - (right - left)
- input数组中, 实际被 数轴上的连续区间
[left, right)
囊括的元素有right-left
个, 那么需要变换的元素 (连续区间以外的元素) 就是len(nums) - (right - left)
这么多个
- input数组中, 实际被 数轴上的连续区间
Time complexity = $O(n\log n + n) = O(n\log n)$
Resource
【每日一题】LeetCode 2009. Minimum Number of Operations to Make Array Continuous, 9/23/2021