CC17-加油站
目录
一、题目描述
二、解题思路
三、代码实现
四、代码解释
五、复杂度分析
一、题目描述
在一条环路上有 n
个加油站,其中第 i
个加油站有汽油 gas[i]
升。你有一辆车,油箱容量无限,从第 i
个加油站开往第 i + 1
个加油站需要消耗汽油 cost[i]
升。你从其中的一个加油站出发,开始时油箱为空。
请判断是否存在一个加油站,从那里出发可以绕环路行驶一周。如果存在,返回出发时加油站的编号;否则,返回 -1
。
说明:答案保证唯一。
示例:输入:gas = [2, 3, 1]
,cost = [3, 1, 2]
,返回值:1
。
二、解题思路
采用贪心算法的思想。我们需要判断总油量是否大于等于总消耗,如果总油量小于总消耗,直接返回 -1
。否则,一定存在一个起始加油站。在遍历过程中,维护当前剩余油量,当当前剩余油量小于 0 时,说明从之前的起始点到当前点都不能作为起始点,将起始点更新为下一个点,并重置当前剩余油量。
三、代码实现
public class Solution {public int canCompleteCircuit(int[] gas, int[] cost) {int n = gas.length;int totalGas = 0;int currentGas = 0;int start = 0;for (int i = 0; i < n; i++) {totalGas += gas[i] - cost[i];currentGas += gas[i] - cost[i];// 如果当前油量为负,说明从start到i的位置都不能作为起点,更新start为i+1,重置currentGasif (currentGas < 0) {start = i + 1;currentGas = 0;}}// 如果总油量小于0,说明无法绕一圈;否则返回startreturn totalGas >= 0 ? start : -1;}// 测试方法public static void main(String[] args) {Solution solution = new Solution();int[] gas = {2, 3, 1};int[] cost = {3, 1, 2};System.out.println("示例输入的起始加油站编号:" + solution.canCompleteCircuit(gas, cost));}
}
四、代码解释
- 初始化变量:
n
为加油站的数量,totalGas
用于统计总剩余油量,currentGas
用于统计当前剩余油量,start
用于记录起始加油站的编号。 - 遍历加油站:在循环中,计算每个加油站的剩余油量(
gas[i] - cost[i]
),并累加到totalGas
和currentGas
中。 - 调整起始点:如果
currentGas
小于 0,说明从之前的start
到当前i
位置都不能作为起始点,将start
更新为i + 1
,并将currentGas
重置为 0,因为从新的起始点开始,当前剩余油量为 0。 - 判断并返回结果:循环结束后,判断
totalGas
是否大于等于 0。如果是,说明存在可以绕一圈的起始点,返回start
;否则,返回-1
。
五、复杂度分析
- 时间复杂度:O(n),其中 n 是加油站的数量。只需要遍历一次数组即可得到结果。
- 空间复杂度:O(1),只需要常数级别的额外空间来存储变量。