最高价值库存,实施细节

时间:2018-07-17 09:26:28

标签: c++ algorithm hash stl

我正在接受采访,并回答了这样的问题:

给股票定价:

MS  | 500   
Apl | 1000  
Nefx| 500   
MS  | 500   

每次出现新库存时,我们都必须添加到现有库存中,或者如果新库存刚刚使它疼痛。因此,其结果应为MS - 1000, Apl - 1000, Nefs - 500.

我们应该具有2个功能:

void add(string, int); // adds new stock  
void display(unsigned n); // displays top n stocks

所以我这样实现:

unordered_map<string, int> UM;
void add(string s, int n)
{
    auto iter = M.find(s);
    if(s==M.end())
    { 
        M[str] = n;
    }
    else
    {
        M[str] += n; 
    }
}

void display(unsigned n)
{
    std::map<int,string> M;
    for(auto iter = UM.begin(); iter!=UM.end(); ++iter)
    {
        M.insert(make_pair(iter->second, iter->first));
    }
    for(auto iter = M.rbegin(); iter!=M.rend(); ++iter)
    {
        if(n==0){break;}
        cout<<iter->second<<" "<<iter->first<<endl;
        n--;
    }
}

如果哈希是完美的,尽管加法函数O(1)非常有效,但是dislpay太慢,O(NlogN)+ n。无论必须显示多少个项目,我们都会操作所有项目。即使需要更改添加功能,有没有更有效的方法来解决该问题?

2 个答案:

答案 0 :(得分:2)

background_image = background_image.putalpha(128) 函数应为单行background_image.putalpha(128) 。没必要了。

  

显示速度太慢,O(NlogN)+ n

您可以将指向add元素的指针复制到向量中,并对UM[s] += n;顶部元素(复杂度UM)进行std::partial_sort

n

有了O(size*log(n))的额外存储空间(而不是上面的void display(unsigned n) { n = std::min<unsigned>(n, UM.size()); std::vector<std::reference_wrapper<decltype(UM)::value_type>> v(UM.begin(), UM.end()); std::partial_sort(v.begin(), v.begin() + n, v.end(), [](auto a, auto b) { return a.get().second > b.get().second; }); for(auto p = v.begin(); n--; ++p) std::cout << p->get().second << " " << p->get().first << '\n'; } ):

O(n)

答案 1 :(得分:0)

类似这样的东西:

struct PriceAndTicker {
    PriceAndTicker(int price, const std::string& ticker)
        : price(price), ticker(ticker) {}

    int price;
    std::string ticker;
};

bool operator<(const PriceAndTicker& lhs, const PriceAndTicker& rhs) {
    return lhs.price > rhs.price
        || (lhs.price == rhs.price && lhs.ticker < rhs.ticker);
}

std::set<PriceAndTicker> priceAndTickers;
std::unordered_map<std::string, std::set<PriceAndTicker>::iterator> tickerLookup;

void add(const std::string& s, int priceChange) {
    int newPrice;
    auto it = tickerLookup.find(s);
    if (it == tickerLookup.end()) {
        newPrice = priceChange;
    } else {
        newPrice = it->second->price + priceChange;
        priceAndTickers.erase(it->second);
    }
    tickerLookup.emplace(
        s, priceAndTickers.emplace(newPrice, s).first);
}

void display(size_t n) {
    size_t counter = 0;
    for (auto it = priceAndTickers.begin(); it != priceAndTickers.end(); ++it) {
        if (counter++ == n) {
            break;
        }
        std::cout << it->ticker << " " << it->price << "\n";
    }
}

add的时间复杂度为O(log N),display的时间复杂度为O(n)。