leetcode之加油站
又是每日一题做的
暴力破解
思路就是从头到尾挨个遍历,从开始加到结束,出现小于0的就进入下一个节点继续遍历
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
if (gas.length < 1)
return 0;
if (gas.length == 1)
return gas[0]>=cost[0]?0:-1;
for (int i = 0; i < gas.length; i++)
{
gas[i] -= cost[i];
}
for (int i = 0; i < gas.length; i++)
{
if (gas[i] > 0)
{
int count = gas[i];
boolean flag = true;
for (int j = ((i + 1) % (gas.length)); j != i;)
{
count += gas[j];
if (count < 0)
{
flag = false;
break;
}
j = ((j + 1) % (gas.length));
}
if (flag)
{
return i;
}
}
}
return -1;
}
}
暴力破解小小优化
每次遍历该节点时,记录下从开始到本位置的加和,往后遍历时,只需要遍历到末尾不需要加上前面的
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
if (gas.length < 1)
return 0;
if (gas.length == 1)
return gas[0] >= cost[0] ? 0 : -1;
int count = 0;
for (int i = 0; i < gas.length; i++)
{
count += gas[i];
gas[i] -= cost[i];
}
if (count < 0)
return -1;
int early = 0;
for (int i = 0; i < gas.length; i++)
{
count = 0;
boolean flag = true;
for (int j = i; j < gas.length; j++)
{
count += gas[j];
if (count < 0)
{
flag = false;
break;
}
}
if (flag)
{
count += early;
if (count >= 0)
return i;
}
early += gas[i];
}
return -1;
}
}
莫名其妙的速度
我的思路是,安排两个类似指针的东西,选取一段数组,如果大于0就让右指针一直向前加,否则就让左指针向前移动,当右指针能够移动到右端点时,即为成功.我总觉得感觉少了点逻辑.后来发现是应该证明,当油和花费差大于0时,肯定有解。 我并没有证明这个问题,准备再加点逻辑判断,会不会中途因为负数太大给断了,但是鬼使神差的点了提交,通过了。反向证明了之前的问题。因为工作问题,暂时不去证明,回来再证明
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
if (gas.length < 1)
return 0;
if (gas.length == 1)
return gas[0] >= cost[0] ? 0 : -1;
int count = 0;
for (int i = 0; i < gas.length; i++)
{
gas[i] -= cost[i];
count += gas[i];
}
if (count < 0)
return -1;
count = 0;
int l = 0, r = 0;
int early = 0;
while (r < gas.length)
{
count += gas[r++];
while (l < r && count < 0)
{
early += gas[l];
count -= gas[l];
l++;
}
}
return l;
}
}