数组补丁

题目  描述:

给出一个从小到大排好序的整数数组nums和一个整数n,在数组中添加若干个补丁(元素)使得[1,n]的区间内的所有数都可以表示成nums中若干个数的和。返回最少需要添加的补丁个数。

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

返回1,表示至少需要添加1个数{2},才可以表示1到6之间所有数。

Example 2:
nums = [1, 5, 10], n = 20

返回2,表示至少需要添加两个数{2,4},才可以表示1到20之间所有数。

分析解答:

读者不难想到暴力搜索的做法:先穷举每一个不在数组里的数p,再穷举判断p是否可以表示为数组中若干个数的和;如果不能,则把p加入数组中,把答案加一。

然而,这种做法时间复杂度高且实际操作难度大(需要考虑穷举的顺序)。我们不妨先思考一个简单的问题,如果nums数组为空,那么最少需要多少个数字才能表示1到n之间所有数?

相信大家都可以想到一个贪心算法,即按照1、2、4、8...(树状数组可以表示1~n中所有数)都顺序添加,每次加入都数都比之前所有数的总和大1,直到总和大于n。

本题的难点是预先给出了一些数,但这不影响我们的贪心策略:假设nums当前至多可以表示1到m之间的所有数,加入m+1;直到m大于等于n

#include<bits/stdc++.h>int num[100];
int main()
{
    int n,m;//要表示1~n中所有的数
    while(scanf("%d",&n)){
        memset(num,0,sizeof(num));
        scanf("%d",&m);//已有数组中有m个数
        for(int i=0;i<m;i++)
            scanf("%d",&num[i]);
        int sum=0,ans=0,index=0;
        if(num[0]==1){
            sum=1;
            index=1;
        }
        while(sum<n){
            while(index<m&&num[index]<=sum){
                sum+=num[index];
                index++;
            }
            if(sum<n){
                if(index<m&&num[index]==sum+1)
                    index++;
                else
                    ans++;
                sum=2*sum+1;
            }
        }
        printf("%d\n",ans);
    }
}
时间: 2024-08-24 18:10:42

数组补丁的相关文章

数组的最少补丁数

距上一次写博客已是好久了,也是因为自己当时心理比较脆弱,面试的时候面试官跟我说我写的这些东西毛用没有确实当时是给我当头一棒,冷水浇头,然而现在领导给了我一些鼓励,所以我就又来耕耘了. 问题: 给一个升序排序后的数组 nums 和一个整数 N,在数组中添加若干个元素(数) 使得 1-N 内所有的数都可以表示成 nums 中若干数的和.求最小需要的补丁数. 无关紧要的吐槽:其实这个问题还是不完整的,数组中允许重复吗? 数组中的元素是否可以重复使用呢? 解决的关键在于要明白一个数学上的事情:最少可以使

[LeetCode] Patching Array 补丁数组

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

C编译器剖析_1.5 结合C语言来学汇编_指针、数组和结构体

让我们再来看一份C代码,及其经UCC编译器编译后产生的主要汇编代码,如图1.33所示,其中包含了数组.指针和结构体. 图1.33 数组.指针和结构体 按照C的语义,图1.33第9行的C代码是对局部数组number的初始化,需要把number[0]初始化为2015,而数组中的其他元素皆被初始化为0.UCC编译器采取的翻译方法是:先调用memset函数来把数组number所占的内存空间清0,然后再把number[0]设为2015,如图1.33的第17至24行所示.C库函数memset的API如下所示

Android 热补丁技术——资源的热修复

前言 今年真是热补丁框架的洪荒之力爆发的一年,短短几个月内,已经出现了好几个热修复的框架了,基本上都是大同小异,这里我就不过多的去评论这些框架.只有自己真正的去经历过,你才会发现其中的 大写的坑 事实上,现在出现的大多数热修复的框架,稳定性和兼容性都还达不到要求,包括阿里的Andfix,据同事说,我们自己的app原本没有多少crash,接入了andfix倒引起了一部分的crash,这不是一个热修复框架所应该具有的"变态功能".虽然阿里百川现在在大力推广这套框架,我依旧不看好,只是其思路

MinHook测试与分析(x86下 E8,E9,EB,CALL指令测试,且逆推测试微软热补丁)

依稀记得第一次接触Hook的概念是在周伟民先生的书中-><<多任务下的数据结构与算法>>,当时觉得Hook的本质就是拦截,就算到现在也是如此认为. 本篇文章是在x86下测试与分析跳转+offset类型的Hook,并且逆推测出热补丁的简单用法,MinHook它的中心就是覆盖重写并且可以复原.知道大概的思路后后让我们先来具体的实现MinHook再去做测试. 首先是堆的申请,这是必要也必须做的,对于微软函数HeapCreate()就不再赘述,以下是实现与卸载 1 NTSTATUS

怎么判断一个对象是不是数组类型?

前面<变量的赋值和对象的赋值>中有用到typeof运算符去判断运算数的类型,结果如下: alert(typeof 1); // 返回字符串"number" alert(typeof "1"); // 返回字符串"string" alert(typeof true); // 返回字符串"boolean" alert(typeof {}); // 返回字符串"object" alert(typeof

各大热补丁方案分析和比较

最近开源界涌现了很多热补丁项目,但从方案上来说,主要包括Dexposed.AndFix.ClassLoader(来源是原QZone,现淘宝的工程师陈钟,在15年年初就已经开始实现)三种.前两个都是阿里巴巴内部的不同团队做的(淘宝和支付宝),后者则来自腾讯的QQ空间团队. 开源界往往一个方案会有好几种实现(比如ClassLoader方案已经有不下三种实现了),但这三种方案的原理却徊然不同,那么让我们来看看它们三者的原理和各自的优缺点吧. Dexposed 基于Xposed的AOP框架,方法级粒度,

索引超出了数组界限(Microsoft.SqlServer.Smo)

SSMS连接远程SQL Server服务器是很方便的. 昨天我用SQL Server 2008 SSMS连接SQL Server 2012竟然报错,如下图: 在网上搜了,参考这个参考那个,太啰嗦了,确实是软件固有的问题,微软肯定会发补丁解决的! 于是看了我的SQL Server 2008的版本,在SSMS界面,帮助--关于.没有类似下面的Windows版本那样明显: 而是10.0.xxxx.x,我只知道10.0的SQL Server 2008,如果前面是10.5就是SQL Server 2008

N个数循环奇数位数的数组解法

原题是这样的:有N个数组成的数组,要求去除奇数位置上的数字,分别打印出这些数字:剩下的数字从新排列,继续去除其中技术位置上的数字,并打印这些数字:以此类推,直到只剩下最后一个数字,要求在屏幕上打印这些数字,并且显示最后剩下的一个数字在原来数组中的位置. 其实这是很有规律的,用数学方法解很方便.想法是第一次去除的是:{1,3,5,7….}全部的奇数,第二次去除的是{1,3,5,7,9…}×2,第三次去除的是{1,3,5,7,9}×2^2以此类推,很容易根据数学规律写出程式出来. 不巧的是下午头脑发