Given a sorted positive integer array nums and an integer n, add/patch elements to the array such that any number in range [1, n] inclusive can be formed by the sum of some elements in the array. Return the minimum number of patches required.

Example 1:
nums = [1, 3]n = 6
Return 1.

Combinations of nums are [1], [3], [1,3], which form possible sums of: 1, 3, 4.
Now if we add/patch 2 to nums, the combinations are: [1], [2], [3], [1,3], [2,3], [1,2,3].
Possible sums are 1, 2, 3, 4, 5, 6, which now covers the range [1, 6].
So we only need 1 patch.

Example 2:
nums = [1, 5, 10]n = 20
Return 2.
The two patches can be [2, 4].

Example 3:
nums = [1, 2, 2]n = 5
Return 0.

Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.

这道题给我们一个有序的正数数组nums,又给了我们一个正整数n,问我们最少需要给nums加几个数字,使其能组成[1,n]之间的所有数字,注意数组中的元素不能重复使用,否则的话只有要有1,就能组成所有的数字了。这道题我又不会了,上网看到了史蒂芬大神的解法,膜拜啊,这里就全部按他的解法来讲吧。我们定义一个变量miss,用来表示[0,n]之间最小的不能表示的值,那么初始化为1,为啥不为0呢,因为n=0没啥意义,直接返回0了。那么此时我们能表示的范围是[0, miss),表示此时我们能表示0到miss-1的数,如果此时的num <= miss,那么我们可以把我们能表示数的范围扩大到[0, miss+num),如果num>miss,那么此时我们需要添加一个数,为了能最大限度的增加表示数范围,我们加上miss它本身,以此类推直至遍历完整个数组,我们可以得到结果。下面我们来举个例子说明:

给定nums = [1, 2, 4, 11, 30], n = 50,我们需要让[0, 50]之间所有的数字都能被nums中的数字之和表示出来。

首先使用1, 2, 4可能表示出0到7之间的所有数,表示范围为[0, 8),但我们不能表示8,因为下一个数字11太大了,所以我们要在数组里加上一个8,此时能表示的范围是[0, 16),那么我们需要插入16吗,答案是不需要,因为我们数组有1和4,可以组成5,而下一个数字11,加一起能组成16,所以有了数组中的11,我们此时能表示的范围扩大到[0, 27),但我们没法表示27,因为30太大了,所以此时我们给数组中加入一个27,那么现在能表示的范围是[0, 54),已经满足要求了,我们总共添加了两个数8和27,所以返回2即可。

解法一:

class Solution {
public:
int minPatches(vector<int>& nums, int n) {
long miss = , res = , i = ;
while (miss <= n) {
if (i < nums.size() && nums[i] <= miss) {
miss += nums[i++];
} else {
miss += miss;
++res;
}
}
return res;
}
};

下面这种方法跟上面那种方法原理都一样,稍有不同之处在于真正的patch了nums数组,把需要插入的数字真正的加入了数组中,那么最后用新数组的长度减去原始长度就知道我们加入了几个数字了。

解法二:

class Solution {
public:
int minPatches(vector<int>& nums, int n) {
long miss = , k = nums.size(), i = ;
while (miss <= n) {
if (i >= nums.size() || nums[i] > miss) {
nums.insert(nums.begin() + i, miss);
}
miss += nums[i++];
}
return nums.size() - k;
}
};

参考资料:

https://leetcode.com/discuss/82895/actually-patching

https://leetcode.com/discuss/82822/solution-explanation

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Patching Array 补丁数组的更多相关文章

  1. [LeetCode] Rotate Array 旋转数组

    Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, the array  ...

  2. LeetCode Patching Array

    原题链接在这里:https://leetcode.com/problems/patching-array/ 题目: Given a sorted positive integer array nums ...

  3. [LeetCode] Contiguous Array 邻近数组

    Given a binary array, find the maximum length of a contiguous subarray with equal number of 0 and 1. ...

  4. [LeetCode] 565. Array Nesting 数组嵌套

    A zero-indexed array A of length N contains all integers from 0 to N-1. Find and return the longest ...

  5. LeetCode Rotate Array 翻转数组

    题意:给定一个数组,将该数组的后k位移动到前n-k位之前.(本题在编程珠玑中第二章有讲) 思路: 方法一:将后K位用vector容器装起来,再移动前n-k位到后面,再将容器内k位插到前面. class ...

  6. C++ STL@ list 应用 (leetcode: Rotate Array)

    STL中的list就是一双向链表,可高效地进行插入删除元素. List 是 C++标准程式库 中的一个 类 ,可以简单视之为双向 连结串行 ,以线性列的方式管理物件集合.list 的特色是在集合的任何 ...

  7. LeetCode 80. 删除排序数组中的重复项 II

    LeetCode 80. 删除排序数组中的重复项 II

  8. LeetCode:将有序数组转换为二叉搜索树【108】

    LeetCode:将有序数组转换为二叉搜索树[108] 题目描述 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差 ...

  9. LeetCode刷题总结-数组篇(上)

    数组是算法中最常用的一种数据结构,也是面试中最常考的考点.在LeetCode题库中,标记为数组类型的习题到目前为止,已累计到了202题.然而,这202道习题并不是每道题只标记为数组一个考点,大部分习题 ...

随机推荐

  1. 读书笔记--SQL必知必会03--排序检索数据

    3.1 排序数据 子句(clause) SQL语句由子句构成.一个子句通常由一个关键字加上所提供的数据组成. ORDER BY子句可以取一个或多个列的名字,将SELECT语句检索出的数据进行排序. O ...

  2. C#基础回顾(一)—C#访问修饰符

    一.写在前面的话 好久没有停下来总结自己,转眼间15年过去好些天,回首过去的日子,亦或失去,亦或所得!生活的节奏,常常让我们带着急急忙忙的节奏去追赶,也许这并不是每个人所期望的生活方式!于他人,于自己 ...

  3. 【中文分词】条件随机场CRF

    之前介绍的MMEM存在着label bias问题,因此Lafferty et al. [1] 提出了CRF (Conditional Random Field). BTW:比较有意思的是,这篇文章的二 ...

  4. 数百个 HTML5 例子学习 HT 图形组件 – 3D 建模篇

    http://www.hightopo.com/demo/pipeline/index.html <数百个 HTML5 例子学习 HT 图形组件 – WebGL 3D 篇>里提到 HT 很 ...

  5. 如果你也会C#,那不妨了解下F#(4):了解函数及常用函数

    函数式编程其实就是按照数学上的函数运算思想来实现计算机上的运算.虽然我们不需要深入了解数学函数的知识,但应该清楚函数式编程的基础是来自于数学. 例如数学函数\(f(x) = x^2+x\),并没有指定 ...

  6. C#——this关键字(1)

    //我的C#是跟着猛哥(刘铁猛)(算是我的正式老师)<C#语言入门详解>学习的,微信上猛哥也给我讲解了一些不懂得地方,对于我来说简直是一笔巨额财富,难得良师! 在学习C#的时候,老师讲的示 ...

  7. 网站美化常见CSS

    伴随网络时代日新月异的发展,用户不仅仅满足于软件系统的功能需求,对软件系统的页面显示效果以及交互模式的要求也逐渐提高.尤其是展示性质的平台页面对于界面美化效果要求更高,有一句话说的好:Html是结构, ...

  8. MFC背景透明

    # 一: # typedef BOOL (WINAPI *lpfnSetLayeredWindowAttributes)(HWND hWnd, COLORREF crKey, BYTE bAlpha, ...

  9. 【Asp.Net Core】一、Visual Studio 2015 和 .NET Core 安装

    安装 Visual Studio 和 .NET Core 1.安装 Visual Studio Community 2015,选择 Community 下载并执行默认安装.Visual Studio ...

  10. alias拦截器的使用

    在SSH项目中,有时需要由一个Action跳转到另一个Action.有两种方式可以实现Action之间的跳转,一种是chain,另一种是redirectAction,这两种方式之间的区别是chain是 ...