forked from azl397985856/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
robot
committed
Sep 25, 2021
1 parent
16d7f27
commit fc224d0
Showing
3 changed files
with
126 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
124 changes: 124 additions & 0 deletions
124
problems/2009.minimum-number-of-operations-to-make-array-continuous.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
## 题目地址(2009. 使数组连续的最少操作数) | ||
|
||
https://leetcode-cn.com/problems/minimum-number-of-operations-to-make-array-continuous/ | ||
|
||
## 题目描述 | ||
|
||
``` | ||
给你一个整数数组 nums 。每一次操作中,你可以将 nums 中 任意 一个元素替换成 任意 整数。 | ||
如果 nums 满足以下条件,那么它是 连续的 : | ||
nums 中所有元素都是 互不相同 的。 | ||
nums 中 最大 元素与 最小 元素的差等于 nums.length - 1 。 | ||
比方说,nums = [4, 2, 5, 3] 是 连续的 ,但是 nums = [1, 2, 3, 5, 6] 不是连续的 。 | ||
请你返回使 nums 连续 的 最少 操作次数。 | ||
示例 1: | ||
输入:nums = [4,2,5,3] | ||
输出:0 | ||
解释:nums 已经是连续的了。 | ||
示例 2: | ||
输入:nums = [1,2,3,5,6] | ||
输出:1 | ||
解释:一个可能的解是将最后一个元素变为 4 。 | ||
结果数组为 [1,2,3,5,4] ,是连续数组。 | ||
示例 3: | ||
输入:nums = [1,10,100,1000] | ||
输出:3 | ||
解释:一个可能的解是: | ||
- 将第二个元素变为 2 。 | ||
- 将第三个元素变为 3 。 | ||
- 将第四个元素变为 4 。 | ||
结果数组为 [1,2,3,4] ,是连续数组。 | ||
提示: | ||
1 <= nums.length <= 105 | ||
1 <= nums[i] <= 109 | ||
``` | ||
|
||
## 前置知识 | ||
|
||
- 二分 | ||
|
||
## 公司 | ||
|
||
- 暂无 | ||
|
||
## 思路 | ||
|
||
由于最终的数组长度一定是原数组长度。 因此题目让我们找最少操作数,其实等价于找最多保留多少个数不变,这样我们就可以通过最少的操作数使得数组连续。 | ||
|
||
朴素的思路是枚举所有的区间 [a,b] 其中 a 和 b 为区间 [min(nums),max(nums)] 中的两个数。这种思路的时间复杂度是 $O(v^2)$,其中 v 为 nums 的值域。看一下数据范围,很明显会超时。 | ||
|
||
我们可以先对数组排序,这样就可以二分找答案,使得时间复杂度降低。看下时间复杂度排序的时间是可以允许的,因此这种解决可以 ac。 | ||
|
||
具体地: | ||
|
||
- 对数组去重 | ||
- 对数组排序 | ||
- 遍历 nums,对于每一个 num 我们都二分找到最左和最右的**满足值域差小于等于 old_n 的索引**,其中 old_n 为去重前的 nums 长度。简单来说,我们需要找到满足值在 [x,num] 范围的最左 x 和满足值在 [num,y] 范围的最右 y | ||
- 满足两个值域范围的区间我们找到了,那么答案区间长度的最大值,也就是 n - 区间长度中的**最小值** | ||
|
||
具体参考下方代码。 | ||
|
||
## 关键点 | ||
|
||
- 反向思考,题目要找最少操作数,其实就是找最多保留多少个数 | ||
|
||
## 代码 | ||
|
||
- 语言支持:Python3 | ||
|
||
Python3 Code: | ||
|
||
```python | ||
|
||
import bisect | ||
|
||
|
||
class Solution: | ||
def minOperations(self, nums: List[int]) -> int: | ||
ans = on = len(nums) | ||
nums = list(set(nums)) | ||
nums.sort() | ||
n = len(nums) | ||
for i, v in enumerate(nums): | ||
r = bisect.bisect_right(nums, v + on - 1) | ||
l = bisect.bisect_left(nums, v - on + 1) | ||
ans = min(ans, n - (r - i), n - (i - l + 1)) | ||
return ans + (on - n) | ||
|
||
``` | ||
|
||
**复杂度分析** | ||
|
||
令 n 为数组长度。 | ||
|
||
- 时间复杂度:$O(nlogn)$ | ||
- 空间复杂度:$O(n)$ | ||
|
||
> 此题解由 [力扣刷题插件](https://leetcode-pp.github.io/leetcode-cheat/?tab=solution-template) 自动生成。 | ||
力扣的小伙伴可以[关注我](https://leetcode-cn.com/u/fe-lucifer/),这样就会第一时间收到我的动态啦~ | ||
|
||
以上就是本文的全部内容了。大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 40K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。 | ||
|
||
关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。 | ||
|
||
![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfcuzagjalj30p00dwabs.jpg) |