其他解决方案的问题在于他们的贪婪选择不是最优的。
一个简单的基于优先队列的解决方案将为这个问题提供最佳解决方案。 min_product 是传递所需数组的函数,映射用于跟踪已经看到的元组。我使用了一个简单的 stl 优先级队列。
//// Asume the vector a(size>=3) is sorted
std::vector<int> a;
struct triplet{
int i,j,k;
};
long long value(triplet& p1){
return (long long)a[p1.i]*(long long)a[p1.j]*a[p1.k];
}
struct CompareTriplet {
bool operator()(triplet const & p1, triplet const & p2) {
return value(p1) > value(p2);
}
};
void push_heap(std::priority_queue<triplet, std::vector<triplet> pq, CompareTriplet>& pq,triplet &t,std::vector<triplet>& m;){
if (m.find(t)!=m.end()){
m[t]=1;
pq.push(t);
}
}
std::vector<long long> min_product(int k){
sort(a.begin(), a.end()); // sort if not sorted.
int n=a.size();
std::unodered_map<triplet,bool> m;
std::vector<long long> MP(k);
std::priority_queue<triplet, std::vector<triplet>, CompareTriplet> pq;
push_heap(pq,triplet{0,1,2},m);
for(int i=0; !pq.empty() and i<k;i++){
auto tp = pq.top(); pq.pop();
MP[i]=value(tp);
if (tp.i+1<tp.j){
push_heap(pq,triplet{tp.i+1,tp.j,tp.k},m);
}
if (tp.j+1<tp.k){
push_heap(pq,triplet{tp.i,tp.j+1,tp.k},m);
}
if (tp.k+1<n){
push_heap(pq,triplet{tp.i,tp.j,tp.k+1},m);
}
}
return MP
}
复杂性:
如果数组没有排序,那么让它排序是这里的瓶颈。实际上在任何时候,我们都需要 top i (
对于已排序的给定数组。
因为堆中最多可以有 2*k 个元素,并且为了获取 MP 的每个元素,需要进行 O(k) 次操作(堆和映射)。因此,运行时间复杂度为 O( k*log(k) )。
是的,它独立于 n。