2007. 从双倍数组中还原原数组
题目地址(2007. 从双倍数组中还原原数组)
https://leetcode-cn.com/problems/find-original-array-from-doubled-array/
题目描述
前置知识
哈希表
公司
暂无
思路
由于 0 乘以 2 等于自身,因此这种情况比较特殊,我们先考虑其他一般情况,最后再加 0 这个特判。
由于 changed 中的最小值一定是原数组中的最小值,同理 changed 中的最大值是原数组中的最大值乘以 2.因此实际上,我们可以确定性得出原数组的两个数了。
那么剩下的数呢?我们可以利用贪心消除法来解决。
即先对 changed 进行排序,并从小到大进行处理。对于 1 <= i <= n - 2, changed[i] 其可能是原数组中的值,也可能是原数组 double 后的值。但是如果其 2 * changes[i]
存在于 changed 中,那么其一定是原数组中的值。
这个结论成立的前提是后面讲的 "遇到这样的匹配我们就将匹配的双方消除"。 试想如果基于这种消除的思想这个结论不成立,那么 changes[i] 一定不会被消除,而只要有一个无法被消除,就是无解的。
这样我们就找到了一对 (changed[i], 2 * changed[i]
),将 changes[i] 加入 ans,并将 2 * changed[i]
从 changed 中移除。
算法:
对 changed 进行排序,这样从左到右遍历的时候,我们可以确保枚举到的是原数组中的项(成立的前提依旧是上面提到的消除)
遍历 changed。 如果 changed[i] * 2 存在且可以和 changed[i] 消除(个数足够,换句话说就是 changed[i] 数目不大于 changed[i]*2 的数目),则进行消除。
如果最后 ans 长度是 changed 一半,说明我们找到了答案,返回即可。否则返回空数组。
关键点
对 changed 进行排序后再处理
代码
语言支持:Python3
Python3 Code:
复杂度分析
令 n 为数组长度。
时间复杂度:$O(n)$
空间复杂度:$O(n)$
相关题目
5966. 还原原数组 2007 和这道题思路类似,都是消除思想。这道题的难点在于 k 是未知的,我们需要先枚举出 k,然后再利用消除思想解决。参考代码:
此题解由 力扣刷题插件 自动生成。
力扣的小伙伴可以关注我,这样就会第一时间收到我的动态啦~
以上就是本文的全部内容了。大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 40K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。
关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。
最后更新于