【笔试题】一个无重复面值的找零算法的思路与实现【方案2】
2012-09-04 01:49
295 查看
给出升序排列的N个数字,比如1, 2, 3, 7, 70
找出无法被这组数字组成的最小正整数。(这组数字中每个数字最多使用一次)
(1)简单描述你的算法和思路。
(2)用C/C++实现
(3)分析你的代码的时间复杂度和空间复杂度
解题思路:
这个问题类似于一个硬币找零问题的升级版。现存在一堆面值为V1, V2, V3, ...的硬币,每种面值的硬币只有一枚,现在需要为顾客找出总值为sum的零钱。问不能被找零的sum的最小值是多少?
方案2:
算法概述
从最小的面值开始计算,依次加入后面的面值算出当前可以组合出的所有总额。如{1, 3, 5},首先1可以组成{1},加上3可以组成{1, 3, 4}...
每次遍历求出组合的可能总额后,可以预先进行一些判断,判断组合中小于等于最大的面值的总额种类是不是与最大面值相等,如果不相等说明已存在不可找零的总额。例如使用最小的两个面值1,3组成总额{1, 3, 4},小于等于最大面值3的总额只有两种,则说明1到3是不连续的自然数,因此已存在不能被找零的总额(遍历查找可知为2)。
在遍历完所有面值之后,查看形成的总额集合是不是连续的,如对{1, 2, 3, 7, ...}进行遍历,由于4不存在,所以不能组成的最小值便是4。
实现
方案二用java进行了实现。(貌似不符合题意= =, anyway, 只是为了回忆下java)
复杂度
todo
找出无法被这组数字组成的最小正整数。(这组数字中每个数字最多使用一次)
(1)简单描述你的算法和思路。
(2)用C/C++实现
(3)分析你的代码的时间复杂度和空间复杂度
解题思路:
这个问题类似于一个硬币找零问题的升级版。现存在一堆面值为V1, V2, V3, ...的硬币,每种面值的硬币只有一枚,现在需要为顾客找出总值为sum的零钱。问不能被找零的sum的最小值是多少?
方案2:
算法概述
从最小的面值开始计算,依次加入后面的面值算出当前可以组合出的所有总额。如{1, 3, 5},首先1可以组成{1},加上3可以组成{1, 3, 4}...
每次遍历求出组合的可能总额后,可以预先进行一些判断,判断组合中小于等于最大的面值的总额种类是不是与最大面值相等,如果不相等说明已存在不可找零的总额。例如使用最小的两个面值1,3组成总额{1, 3, 4},小于等于最大面值3的总额只有两种,则说明1到3是不连续的自然数,因此已存在不能被找零的总额(遍历查找可知为2)。
在遍历完所有面值之后,查看形成的总额集合是不是连续的,如对{1, 2, 3, 7, ...}进行遍历,由于4不存在,所以不能组成的最小值便是4。
实现
方案二用java进行了实现。(貌似不符合题意= =, anyway, 只是为了回忆下java)
import java.util.ArrayList; import java.util.Collections; public class ChangeAlgorithm { public static void main(String args[]) { Integer[] values = {1, 2,3,7, 20};//the face value of the money ArrayList<Integer> sumList = new ArrayList<Integer>(); //the sum values //loops to calculate all possible sum values for(int i=0;i<values.length;i++){ //try to find all possible sum values with the first 'i' face values int size=sumList.size(); for(int j=0;j<size;j++){ Integer item=values[i]+sumList.get(j); if(sumList.indexOf(item)==-1){ sumList.add(item); } } if(sumList.indexOf(values[i])==-1){ sumList.add(values[i]); } Collections.sort(sumList); //if the number of possible sum values are not equal to the face value if(!values[i].equals(sumList.indexOf(values[i])+1)){ break; } } //find the impossible sum value for(int i=0;i<sumList.size();i++){ if(sumList.get(i)!=i+1){ System.out.println((i+1)+" is the minimum."); break; } } } }
复杂度
todo
相关文章推荐
- 【笔试题】一个无重复面值的找零算法的思路与实现
- 一个无重复面值的找零算法的思路与实现(二)
- 一个无重复面值的找零算法的思路与实现
- 用两个栈实现一个队列的功能?要求给出算法和思路!
- 整型数组处理算法(九)给定任意一个正整数,求比这个数大且最小的“不重复数”(性能优化)[2014百度笔试题]
- 设计一个算法,要求在20个数字中(0到19)随机选取十个数字,但是这十个数字不能重复(用C语言或者OC实现)
- (转)js在数组中删除重复的元素自保留一个(两种实现思路)
- 每日一题(33)——用两个栈实现一个队列的功能?要求给出算法和思路
- 整型数组处理算法(九)给定任意一个正整数,求比这个数大且最小的“不重复数”(性能优化)[2014百度笔试题]
- 有一堆扑克牌,其中某张牌的张数超过了扑克牌总数的一半,请找到这张牌。写出算法思路、代码实现和算法的时间复杂度,要求算法尽可能高效。假设给定一个扑克牌的数组poker和它的大小n,请返回所求的扑克牌。
- pythons实现LRU算法,纯属个人思路,重复造轮子。
- js在数组中删除重复的元素自保留一个(两种实现思路)
- 【小米笔试题】实现一个算法,确定一个字符串的所有字符是否全部不同
- 请编程实现:产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复(百度了一下,get一种高性能算法,非递归)
- 一个java笔试题的实现:用5位字符表示日期,并且要求500年不能重复
- 企鹅2015校招笔试之(二)整形长度算法思路实现
- 企鹅2015校招笔试之(一)抽奖算法思路实现
- 【安卓-自定义布局】安卓App开发思路 一步一个脚印(十四)实现Fragment的缓冲视图和数据,防止重复加载
- 已知需要找给顾客的零钱金额为N,当前钱币的面值种类为1,9,10三种,求找给顾客尽量少的钱币数的找零方法,给出程序算法设计思路