LeetCode Gas Station
题目如下:
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.
最简单的想法就是,对每个起点进行搜索,如果能到下一个加油站的话,就继续,知道搜索到一条完整的路径。根据这个想法能很容易得到以下的代码:
1 int canCompleteCircuit(int gas[], int cost[], int n) { 2 int i,j,val=0,count; 3 for(i=0;i<n;i++){ 4 j=i,count=0; 5 while(count!=n){ 6 if(val+gas[j]-cost[j]<0) 7 break; 8 else{ 9 val=val+gas[j]-cost[j]; 10 j++; 11 if(j==n) 12 j=0; 13 count++; 14 } 15 } 16 if(count==8) 17 return i; 18 } 19 return -1; 20 }
当然这个方法是可以运行的,但是算法复杂度为O[n^2],实际提交时也发现Time Limit Exceeded了;
现在想想其它的方法,如果可以从第i个加油站到第j个加油站的话,那么在之后的搜索过程中是不需要再重新搜索i~j这一段的,只要能够到达i加油站,就意味着必然能够到达j加油站。
实行起来当然要使用最合适的数据结构,在这里使用循环链表,得到下面的方法。
1 typedef struct node{ 2 int ID,cost; 3 struct node * next; 4 }node; 5 6 void findPath(node *head){ 7 int val=0; 8 node *p=head; 9 while(val+p->cost>0){ 10 val+=p->cost; 11 if(p->next==head) 12 break; 13 p=p->next; 14 } 15 head->cost=val+p->cost; 16 head->next=p->next; 17 } 18 19 int canCompleteCircuit(int gas[], int cost[], int n) { 20 if(n==1) 21 if(gas[0]>=cost[0]) 22 return 0; 23 else 24 return -1; 25 int i,pilot=1; 26 node *ans =(node*)malloc(sizeof(node)*n); 27 node *p=ans; 28 for(i=0;i<n;i++){ 29 ans[i].ID=i; 30 ans[i].next=&ans[(i+1)%n]; 31 ans[i].cost=gas[i]-cost[i]; 32 } 33 while(1){ 34 if(p->next==p) 35 return p->ID; 36 while(p->cost<=0){ 37 p=p->next; 38 pilot++; 39 if(pilot>n) 40 return -1; 41 } 42 findPath(p); 43 } 44 }
注意其中对于没有路径的情况的处理,我在这偷了个懒,用pilot++直到大于n来做判断,实际这里应该是可以优化的。
这段代码的实际运行时间是4ms,缺点显而易见,创建循环链表耗用了大量内存。
就酱。

浙公网安备 33010602011771号