我在黑客等级上被问到了这一点,但我还没有找到一个没有分配时间的解决方案。我使用php并且分配的时间是9秒......
这个想法是有#"门票摊位"有一定数量的门票,比如说9,他们卖的任何门票都是以剩下的门票数量为准,所以第一张门票是9美元,第二张是8美元......等等。
你给了两行数据,比如说:
2 4
1 5
第一行包含两个数字:
第二行包含每个摊位最初有多少张票的列表,所以在这种情况下,摊位1有1张票,摊位2有5张票。
问题:出售给定票数的最高金额是多少?
在这种情况下,您以5 + 4 + 3 + 2 = 14美元的价格从摊位2卖出4张票
那你怎么解决呢我想出了两种方法,两种方式都耗尽了时间
将档位号(第二行)加载到数组中。通过该阵列N次(销售门票的数量)选择最大数量,将其添加到聚合器,减少该数量。然后你在聚合器中得到总数。
将档位编号加载到数组中。对数组进行排序。向后遍历数组并执行:存储该数字(当前),将其添加到聚合器,转到下一个值。如果它是相同的(当前),则将其添加到聚合器,从中减去1,继续。如果不同,请返回到数组的末尾并重新开始。做N次(内部循环,而不是外部循环)。
问题:两个人都没有工作。
有人能想到更好的解决方案吗?
答案 0 :(得分:3)
还有一种明显的方法可以通过乘以MIN(最高档数,剩余售票数)来改善这一点。
注意:为了使其表现良好,您的实现语言必须具有真正的数组(即,无论索引如何,都是恒定的访问时间)。我不懂PHP,但是有些语言(JS?)使用顺序列表来模仿数组,但是没有相同的性能。
以下是上述方法的Java实现(阅读评论以便更好地理解):
int[] stalls = new int[] { 4, 7, 1, 4, 8, 8 };
int t = 4;
Arrays.sort(stalls);
int tickets = stalls[stalls.length - 1];
int[] dp = new int[tickets + 1];
for (int i = 0; i < stalls.length; i++) {
dp[stalls[i]]++;
}
int total = 0;
int i = dp.length - 1;
while (t > 0) {
if (dp[i] > 0) {
total += i;
t--;
dp[i]--;
dp[i - 1]++;
} else {
i--;
}
}
System.out.println(total);
答案 1 :(得分:2)
如果您担心DP,这是您应该尝试的O(n)解决方案。以下代码仅考虑最大元素,然后继续减少它,直到达到所需的票数。通过将其作为值存储在hashMap中,它可以跟踪乘法因子。最后,如果票数大于所需票数,它将从结果中减去最近添加的票价,直到票数等于所需票数为止。
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class TicketClass {
public static void main(String[] args){
int[] arr = {10,10,2,8,6,4};
int ticket = 23;
Arrays.sort(arr);
int mul = 1;
int k = 0;
System.out.print("Hello World");
long res = 0;
Map<Integer,Integer> hm = new HashMap<>();
for(int i:arr){
if(hm.containsKey(i)){
hm.put(i,hm.get(i)+1);
}
else
hm.put(i,1);
}
int curr = arr[arr.length-1];
while(k < ticket){
mul=hm.getOrDefault(curr,mul);
res += curr*mul;
curr--;
k += mul;
if(hm.containsKey(curr))
hm.put(curr,hm.get(curr)+mul);
}
//End of while loop
curr++;
while(k > ticket){
k--;
res -=curr;
}
System.out.println("ticket "+k);
System.out.println(res);
}
}
答案 2 :(得分:0)
让我们看看为什么你的解决方案会超时。
将失速编号(第二行)加载到数组中。通过那个 数组N次(卖出的门票数量)选择最大 编号,将其添加到聚合器,减少该数量。 然后你在聚合器中得到总数。
这是O(N * M),其中N
是要售卖的门票数量,M
是售票亭的数量。这几乎是一种蛮力的方法,通常不足以击败黑客的测试。
将档位号加载到数组中。对数组进行排序。倒退 通过数组和你一样:存储该数字(当前),添加它 到聚合器,转到下一个值。如果它是相同的(当前), 然后将其添加到聚合器,从中减去1,继续。如果是 不同,回到数组的末尾,然后重新开始。做那个N. 时间(内部循环,而不是外部循环)。
也许是我,但我真的不明白你的意思。从我看来,听起来这仍然是O(N * M)。你如何处理大量票数减少很多次的情况,以至于它破坏了你之前的那种?
这里需要的是一个可以有效检索当前最大值的数据结构,和可以有效地弹出/插入新元素。看起来最大堆是一个很好的候选者。只需在每个展位中保留最大堆中的可用票数。要通过N
展位销售M
张票,请N
次执行此操作:
总体复杂度为O(N*log(M))
,这可能是您可以做的最好的。
C ++实现:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int max_revenue(vector<int> &tickets, int n) {
make_heap(tickets.begin(), tickets.end());
int res = 0;
for (int i = 0; i < n; i++) {
res += tickets.front();
pop_heap(tickets.begin(), tickets.end());
tickets[tickets.size()-1]--;
push_heap(tickets.begin(), tickets.end());
}
return res;
}
int main(void) {
int booths;
cin >> booths;
int n;
cin >> n;
vector<int> tickets(booths);
for (int i = 0; i < booths; i++)
cin >> tickets[i];
cout << max_revenue(tickets, n) << endl;
return 0;
}
答案 3 :(得分:0)
对MaxHeap解决方案的优化很少:
您无需逐个删除票证。如果您有一个顶部窗口,您需要知道它有多少票,以及下一张票有多少票。然后,您可以删除差异并在一次操作中计算总价 如果您有多个具有相同最大票数的窗口,只需稍作修改即可。
答案 4 :(得分:0)
这是PHP中的一个实现,这不像其他一些答案那样创建一个额外的数组。总是有很多不同的方法来解决这个问题,看看这个问题,它可能会在未来给你提供想法。有很多方法可以改进实际使用,但这只是为了显示快速解决问题的替代方法
class booth {
public $booths = [];
public $left = 0;
public $count = 0;
public $total = 0;
public $booth = 0;
public $nextBooth = 0;
function __construct() {
$this->booths = [3, 7, 5, 2, 0, 2, 5, 15, 9, 1, 39, 91, 0, 58, 29];
$this->left = 25;
sort($this->booths);
$this->booth = array_pop($this->booths);
while($this->left > 0 && count($this->booths) > 0) {
$this->count++;
$this->nextBooth = array_pop($this->booths);
$this->countTotal($this->booth - $this->nextBooth);
}
// found end of array -- clear out any that are left
if($this->left > 0)
$this->countTotal(1);
echo "total: " + $this->total."\r\n";
}
// everything global except loops
function countTotal($loops) {
for($i = 0; $i < $loops, $this->left > 0; $i++) {
if ($this->count > $this->left)
$this->count = $this->left;
$this->total += $this->booth * $this->count;
$this->left -= $this->count;
$this->booth--;
}
}
}
new booth();