134.加油站 思路: 两个非空的长度相等的数组gas和cost,分别代表在每个位置可以获得的油量以及到下一个地方需耗费的油量; 车的起始油量为0,找出可以安全走完一圈的起始点; 结果如果存在必唯一,就返回起始点下标,否则返回-1;
暴力: O(n^2):两层循环; O(n):外层循环长度为n,每层需要O(1)内存; 分别尝试以每一个位置为起始点,看是否能绕完一圈;
class Solution {
public :
int canCompleteCircuit ( vector< int > & gas, vector< int > & cost) {
int len = cost. size ( ) ;
for ( int i = 0 ; i < len; ++ i) {
int rest = gas[ i] - cost[ i] ;
int index = ( i + 1 ) % len;
while ( rest > 0 && index != i) {
rest + = gas[ index] - cost[ index] ;
index = ( index + 1 ) % len;
}
if ( rest >= 0 && index == i) return i;
}
return - 1 ;
}
} ;
贪心: 首先总获得>=总消耗,才能保证有解(题目说是存在如果有解则是唯一解); 有解的前提下,目标就是寻找那个唯一可行的起始点start,那么那个可行的起始位置一定能保证:在绕一圈的过程中,在每个位置上剩余油量都>=0; rest为gas和cost的差,rest[i]代表在每个位置获得的绝对油量; 从0开始寻找可行start,一旦绝对油量和curSum<0,代表[0, i]都不能作为start,因为这段路程的绝对油量和不够用。因此可选的start起码从i + 1开始;
class Solution {
public :
int canCompleteCircuit ( vector< int > & gas, vector< int > & cost) {
int len = cost. size ( ) ;
int totalSum = 0 ;
int curSum = 0 ;
int start = 0 ;
for ( int i = 0 ; i < len; ++ i) {
totalSum + = gas[ i] - cost[ i] ;
curSum + = gas[ i] - cost[ i] ;
if ( curSum < 0 ) {
curSum = 0 ;
start = i + 1 ;
}
}
if ( totalSum < 0 ) return - 1 ;
return start;
}
} ;
本题贪心: 先保证有解,再去找解; 当前累加rest[i]的和curSum一旦<0,解start至少是i + 1;