您的位置:首页 > 其它

LeetCode Gas Station

2015-03-16 17:03 211 查看
题目如下:


There are N gas stations along a circular route, where the amount of gas at station i is
gas[i]
.

You have a car with an unlimited gas tank and it costs
cost[i]
of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.

Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.

Note:
The solution is guaranteed to be unique.



  最简单的想法就是,对每个起点进行搜索,如果能到下一个加油站的话,就继续,知道搜索到一条完整的路径。根据这个想法能很容易得到以下的代码:

int canCompleteCircuit(int gas[], int cost[], int n) {
int i,j,val=0,count;
for(i=0;i<n;i++){
j=i,count=0;
while(count!=n){
if(val+gas[j]-cost[j]<0)
break;
else{
val=val+gas[j]-cost[j];
j++;
if(j==n)
j=0;
count++;
}
}
if(count==8)
return i;
}
return -1;
}


  当然这个方法是可以运行的,但是算法复杂度为O[n^2],实际提交时也发现Time Limit Exceeded了;

  现在想想其它的方法,如果可以从第i个加油站到第j个加油站的话,那么在之后的搜索过程中是不需要再重新搜索i~j这一段的,只要能够到达i加油站,就意味着必然能够到达j加油站。

  实行起来当然要使用最合适的数据结构,在这里使用循环链表,得到下面的方法。

typedef struct node{
int ID,cost;
struct node * next;
}node;

void findPath(node *head){
int val=0;
node *p=head;
while(val+p->cost>0){
val+=p->cost;
if(p->next==head)
break;
p=p->next;
}
head->cost=val+p->cost;
head->next=p->next;
}

int canCompleteCircuit(int gas[], int cost[], int n) {
if(n==1)
if(gas[0]>=cost[0])
return 0;
else
return -1;
int i,pilot=1;
node *ans =(node*)malloc(sizeof(node)*n);
node *p=ans;
for(i=0;i<n;i++){
ans[i].ID=i;
ans[i].next=&ans[(i+1)%n];
ans[i].cost=gas[i]-cost[i];
}
while(1){
if(p->next==p)
return p->ID;
while(p->cost<=0){
p=p->next;
pilot++;
if(pilot>n)
return -1;
}
findPath(p);
}
}


  注意其中对于没有路径的情况的处理,我在这偷了个懒,用pilot++直到大于n来做判断,实际这里应该是可以优化的。

  这段代码的实际运行时间是4ms,缺点显而易见,创建循环链表耗用了大量内存。

就酱。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: