最小硬币变化-动态编程

时间:2020-03-14 15:06:28

标签: c++ algorithm data-structures dynamic-programming coin-change

问题-您获得了不同面额的硬币和总金额。编写一个函数来计算组成该数量所需的最少数量的硬币。那里有无限量的硬币。

我的方法-我遵循​​了自上而下的方法,但是使用map stl进行记忆时,我获得了TLE。请帮助找出错误并估算时间复杂度。

这是我的代码-

// for example coins v = {1,2} and W = 2 then possible solutions are -
// (2) or (1, 1), therefore minimum number of coins required is 1.
// Below is the function calculating the minimum number of coins required for change

int minCoinChange(vector<int> &v, int start, int W, unordered_map<string, int> &lookup){

// v denoting the vector conataining coins with given denomination
// start denoting the start index i.e. 0(initially)
// W denoting the required change
// lookup is map stl for storing values.

// base cases 
    if(W<0){
        return INT_MAX;
    }
    if(W == 0){
        return 0;
    }
    if(start >= v.size()){
        return INT_MAX;
    }

// for memoization creating the "key"
    string key = to_string(start) + '|' + to_string(W);

// if the key is not found in map then go inside if 
    if(lookup.find(key) == lookup.end()){
        int excl = minCoinChange(v, start+1, W, lookup); // if element is excluded

        int incl = 1 + minCoinChange(v, start, W - v[start], lookup); if element is included 

        lookup[key] = min(incl, excl); // calculating minimum number of coins required and storing in map 
    }
// if key is already there then return value stored in map 
    return lookup[key]; 
}

1 个答案:

答案 0 :(得分:0)

首先,unordered_map的查询时间最差O(n)。有多种方法可以优化unordered_map的性能,例如使用map.reserve(n)保留存储桶数,其中n是您希望在地图中包含的唯一商品的数量。

您可以使用map来代替O(log(n)),这是最坏情况的O(n * W)查找时间,但是由于该算法的时间复杂度为n,因此您的W和{{1} }足够小以适合数组,然后您将O(1)查找起来。

下面是对函数的修改,改为使用数组查找:

int minCoinChange(vector<int> &v, int start, int W, vector<vector<int>> &lookup){

    // v denoting the vector conataining coins with given denomination
    // start denoting the start index i.e. 0(initially)
    // W denoting the required change
    // lookup is 2d vector for storing already computed values.

    // base cases 
    if (W<0) {
        return 1e9;
    }
    if (W == 0) {
        return 0;
    }
    if (start >= v.size()) {
        return 1e9;
    }

    // if this state wasn't computed before
    if (lookup[start][W] == -1) {
        int excl = minCoinChange(v, start+1, W, lookup); // if element is excluded

        int incl = 1 + minCoinChange(v, start, W - v[start], lookup); // if element is included 

        lookup[start][W] = min(incl, excl); // calculating minimum number of coins required and storing in map 
    }
    // return the saved value
    return lookup[start][W];
}

注意:

对于基本情况,请使用INT_MAX之类的方法,而不是使用将1添加到其中的10^9