问题:
假设有一个圆圈。那个圆圈上有n个加油泵。 您将获得两组数据。
- 汽油泵给汽油的量。
- 从汽油泵到下一个汽油泵的距离。
醇>计算卡车能够完成的第一个点 圈子
我刚刚解决了这个问题。我想知道我是否正确解决了问题。
算法:
我从起点开始,我尝试添加剩下的汽油离开了远处。如果值是< 0如果我们再次开始,则不存在解决方案。否则一直循环直到你到达终点。结束总是开始+ 1;我也知道算法O(n)。有人也可以用一个好的逻辑解释它的O(n)。
int PPT(int P[], int D[], int N)
{
int start = 0, end = 1, cur_ptr = P[0] - D[0], i = start;
while(start != end)
{
if(cur_ptr < 0)
{
start = (i + 1) % N;
end = (start + 1) % N;
cur_ptr = 0;
if(start == 0) return -1; // if start again becomes 0 then no solution exists
}
i = (i + 1) % N;
cur_ptr += P[i] - D[i];
}
}
答案 0 :(得分:7)
start != end
总是成立。因此,如果有解决方案,您的算法会产生无限循环。此外,我不明白,为什么end
应该是start + 1
。
这是另一种方法:
考虑以下功能:
此功能在到达泵i
之前计算剩余的汽油。该功能可以如下显示:
该功能从petrol = 0
开始。您看到此配置无效,因为在泵4处剩余的汽油是负的。此外,有一个解决方案,因为最后一个泵(再次启动泵)的剩余汽油是正的。
如果我们选择不同的开始会发生什么?功能的基本形状保持不变。它只是向左移动。此外,因为函数从petrol = 0
开始,函数减少C(start)
。最后剩余的燃料在这种情况下不起作用,因为它会增加目前的汽油。
任务是找到允许所有start
为正的C(i)
。对于最小C(i)
,显然就是这种情况,在本例中为start = 4
。
计算函数C(i)
可以迭代完成,因此可以在线性时间内完成。您可以从0到N迭代一次。在此迭代期间可以在恒定时间内找到最小值(通过与当前最小值进行比较)。因此,总体时间复杂度为O(n)
。
答案 1 :(得分:0)
我认为您提供的解决方案不正确。只要cur_ptr
大于0,您就不会更新变量end
。因此,假设在每个站点P[i] > D[i]
,循环将继续运行直到无穷大。
除了一些更改,我相信您需要在某处添加end = (end + 1) % N;
。我修改了代码并提供了正确的解决方案。
int PPT(int[] P, int[] D, int N)
{
int start = 0, end = 1, cur_ptr = P[0] - D[0];
bool none = false;
while (start != end)
{
if (cur_ptr < 0)
{
start = (start + 1) % N;
if (start == 0) // all stations have been traveled but solution is not yet available
{
none = true;
break;
}
end = (start + 1) % N;
cur_ptr = P[start] - D[start];
}
else
{
end = (end + 1) % N;
cur_ptr += P[end] - D[end];
}
}
return none?-1:start;
}