一个无重复面值的找零算法的思路与实现(找出无法被这组数字组成的最小正整数)

https://blog.csdn.net/maggiedorami/article/details/7932419  

给出升序排列的N个数字,比如1, 2, 3, 7, 70

找出无法被这组数字组成的最小正整数。(这组数字中每个数字最多使用一次)

(1)简单描述你的算法和思路。
(2)用C/C++实现

(3)分析你的代码的时间复杂度和空间复杂度

解题思路:

这个问题类似于一个硬币找零问题的升级版。现存在一堆面值为V1, V2, V3, ...的硬币,每种面值的硬币只有一枚,现在需要为顾客找出总值为sum的零钱。问不能被找零的sum的最小值是多少?

//=======================================================================

int recursion(int values[], int j, int sum)
{
    int i,k;
    if(j<0 && sum>0)
    {
        return -1; /*不能被找零*/
    }
    
    if(sum==0)
        return 0; /*可以被找零*/
        
    /*找出最接近sum且不大于sum,小于values[j]的面值在values数组中的下标*/
    for(i=j; i>=0; --i)
    {
        if(values[i] <=sum)
        {
            k=i;
            break; 
        }
    }
    
    return recursion(values, k-1,sum-values[k]);
            
}


int main(int argc, char** argv) {
    int size=4;
    int values[size]={1,2,3,12};/*升序排列的所有面值,必须先排序*/ 
    
    int sum;
    
    /*如果最小的币值都大于1,则1必定不能被找零*/
    if(values[0]>1) 
    {
        printf("1 is the minimum\n");
    }
    else
    {
        for(int sum=1; ; ++sum)
        {
            int i,j;
            
            /*找出最接近sum且不大于sum的面值在values数组中的下标*/
            for(i=size-1; i>=0; --i)
            {
                if(values[i] <=sum)
                {
                    j=i;
                    break; 
                }
            }
            
            if(recursion(values, j-1, sum-values[j]) == -1)
            {
                printf("%d is the minimum\n", sum);
                break;
            }
        }
    }
  
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_20398345/article/details/81108191