您的位置:首页 > 其它

【笔试题】一个无重复面值的找零算法的思路与实现【方案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)
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐