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,缺点显而易见,创建循环链表耗用了大量内存。

就酱。

posted @ 2015-03-16 17:03  asawang  阅读(154)  评论(0)    收藏  举报