在一条环路上有 n 个加油站,其中第 i 个加油站有 gas[i] 升油,假设汽车油箱容量无限,从第 i 个加油站驶往第 (i+1)%n 个加油站需要花费 cost[i] 升油。
请问能否绕环路行驶一周,如果可以则返回出发的加油站编号,如果不能,则返回 -1。
题目数据可以保证最多有一个答案。
数据范围:
, gas 和 cost 数组中的值满足 
[1,2,3,4,5],[3,4,5,1,2]
3
只能从下标为 3 的加油站开始完成 (即第四个加油站)
[0,10],[9,1]
1
[2,3,4],[3,4,5]
-1
无论从哪个加油站出发都无法环绕环道一圈
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param gas int整型一维数组
* @param cost int整型一维数组
* @return int整型
*/
public int gasStation (int[] gas, int[] cost) {
// write code here
LinkedList<Integer> candicates = new LinkedList<>();
int n = gas.length;
for(int i = 0; i < n; i++){
gas[i] -= cost[i];
if(gas[i] >= 0){
candicates.add(i);
}
}
while(!candicates.isEmpty()){
int startPoint = gameStarted(gas, candicates.removeFirst());
if(startPoint != -1){
return startPoint;
}
}
return -1;
}
private int gameStarted(int[] energy, int start) {
int cur = start;
int cumsum = energy[cur];
cur++;
if(cur == energy.length) cur = 0;
while(cur != start){
if(cumsum >= 0){
cumsum += energy[cur];
cur++;
if(cur == energy.length) cur = 0;
}else{
return -1; // 累加一圈出现了负数
}
}
return start;
}
} 解题思路:挨个检查是否满足gas[i] - cost[i] >= 0 如果满足,则说明该加油站有充足的油驶往下一个加油站,则开始模拟加油过程。时间复杂度o(n^2).
import java.util.*;
public class Solution {
public int gasStation (int[] gas, int[] cost) {
int res = 0;
for(int i = 0; i < gas.length; ++i) {
if(gas[i] < cost[i]) continue;
res = gas[i];
for(int j = 0; j < gas.length; ++j) {
res -= cost[(j + i) % gas.length];
if(res < 0) break;
res += gas[(j + i + 1) % gas.length];
}
if(res >= 0) return i;
}
return -1;
}
}
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* @param gas int整型一维数组
* @param cost int整型一维数组
* @return int整型
*/
public int gasStation(int[] gas, int[] cost) {
int n = gas.length;
// 用一个数组来存储每个加油站的油量差:gas[i] - cost[i]
int[] left = new int[n * 2];
for (int i = 0; i < n; i++) {
left[i] = gas[i] - cost[i]; // 前半部分:从前往后计算油量差
left[n + i] = left[i]; // 后半部分:复制前半部分,模拟环形路线
}
// 计算从每个加油站出发的情况
int index = 0; // 从第一个加油站开始
while (index < n) {
if (left[index] < 0) {
index++; // 如果当前位置油量不足,跳过这个点
continue;
}
boolean flag = true; // 假设从index出发能绕一圈
int tmp = 0; // 当前油量
// 从index开始,向后检查是否能够顺利绕一圈
for (int i = index; i < left.length && flag; i++) {
tmp += left[i]; // 累加油量差
if (tmp < 0) { // 如果油量为负,表示无法继续
flag = false;
}
}
// 如果前面没有失败,再从环的前半部分继续检查
for (int i = 0; i < index && flag; i++) {
tmp += left[i]; // 累加油量差
if (tmp < 0) { // 如果油量为负,表示无法继续
flag = false;
}
}
// 如果能够绕一圈,返回当前的出发点index
if (flag) {
return index;
}
// 如果无法绕一圈,继续尝试下一个出发点
index++;
}
// 如果所有起点都无法绕一圈,返回-1
return -1;
}
}
public class Solution {
public int gasStation(int[] gas, int[] cost) {
int totalTank = 0;
int currTank = 0;
int startingStation = 0;
int n = gas.length;
for (int i = 0; i < n; ++i) {
totalTank += gas[i] - cost[i];
currTank += gas[i] - cost[i];
// 如果当前油量小于0,不可能从前面任何站点出发到达此站点
if (currTank < 0) {
// 设置下一个站点为新的起点
startingStation = i + 1;
// 重置当前油量
currTank = 0;
}
}
// 汽油总量不够加油的,直接返回 -1
return totalTank >= 0 ? startingStation : -1;
}
} static const auto io_sync_off = [](){
std::ios::sync_with_stdio(false);
std::cout.tie(nullptr);
std::cin.tie(nullptr);
return nullptr;
}();
class Solution {
public:
int gasStation(vector<int>& gas, vector<int>& cost) {
int curSum=0;
int min=INT_MAX;
for(int i=0;i<gas.size();i++)
{
int rest=gas[i]-cost[i];
curSum+=rest;
if(curSum<min)
min=curSum;
}
if(curSum<0)
return -1;
if(min>=0)
return 0;
for(int i=gas.size()-1;i>=0;i--)
{
int rest=gas[i]-cost[i];
min+=rest;
if(min>=0)
return i;
}
return -1;
}
}; import java.util.*;
// 这个题, 和简单题,求子序列的最大和,有点像
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param gas int整型一维数组
* @param cost int整型一维数组
* @return int整型
*/
public int gasStation (int[] gas, int[] cost) {
// write code here
// *)
int s = 0;
int sum = 0;
int n = gas.length;
for (int i = 0; i < n; i++) {
int delta = gas[i] - cost[i];
sum += delta;
// 维护子序列的和 >= 0, 移动子序列的头指针
while (sum < 0 && s <= i) {
sum -= (gas[s] - cost[s]);
s++;
}
}
// 补剩下的环
for (int i = 0; i < s; i++) {
sum += (gas[i] - cost[i]);
}
if (sum >= 0) {
return s;
}
return -1;
}
} import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param gas int整型一维数组
* @param cost int整型一维数组
* @return int整型
*/
public int gasStation (int[] gas, int[] cost) {
int spare=0;
int minspare=Integer.MAX_VALUE;
int index=0;
for(int i=0;i<gas.length;i++){
spare+=gas[i]-cost[i];
if(spare<minspare){
minspare=spare;
index=i;
}
}
return spare>=0?index+1:-1;
// write code here
}
} import java.util.*;
public class Solution {
public int gasStation (int[] gas, int[] cost) {
// write code here
int gasCapacity = 0;
int begin = -1;
for (;;) {
begin++;
if (begin == gas.length) return -1; //走完一圈没有发现有站点满足需求 返回-1
for (int i = begin; i < begin + gas.length; i++) {
gasCapacity += gas[i % gas.length]; //膜一下,当超出范围会回到起点
gasCapacity -= cost[i % gas.length];
if (gasCapacity < 0) { //当前站点累计的汽油不足以到下一个站点
gasCapacity = 0;
break;
}
if (i == begin + gas.length - 1) { //判断是否已经走了一圈,返回这个初始站点的位置
return begin;
}
}
}
}
}