【LEETCODE】模拟面试-134-Gas Station
新生
题目:
https://leetcode.com/problems/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.
分析:
This question is to find the start point where the car can complete a circuit.
Input: two arrays, one represents the gas at each station point, another one is cost when the car travels from point i to point i+1. **Output: **if the car can't finish a whole circuit, return -1, if yes, return the index of start point. Note: there maybe multiple solutions, but we just need one path.
The brute force method is that we can scan from 0 to last, each point will be considered as the start once. For each start, we will iterate all the following points in the circuit, and calculate the left gas. If the gas decreases below 0 during the process, this start point is failing, so we can move to next start point. If this start can complete the circuit, we can return its index, and no need to continue searching.
But how to optimize above method? We can reduce some repeated work. Take this data set as an example:
index: |
0, |
1, |
2, |
3, |
4, |
5, |
6 |
---|---|---|---|---|---|---|---|
gas: |
3, |
4, |
3, |
6, |
7, |
1, |
2 |
cost: |
2, |
4, |
5, |
1, |
5, |
1, |
3 |
Since we only care about the left gas at each point, we can firstly transform two arrays to one:
leftGas: |
1, |
0, |
-2, |
5, |
2, |
0, |
-1 |
---|
Suppose this, when we start from index=0, and we can move on till index=2, since the sum_leftGas here is 1, but we can't move to index=3. Then we can just ignore index=1,2 without considering them as start point, since they will be stuck at index_3 too.
And we continue from point index_3, it turns out all the left gas at each station can be >=0, so index_3 can be a start point.
This process is like a Queue: since we scan from 0 to 3, and 0,1,2 fails to be a start, so we pop them out, and continue from 3 to 4,5,6,0,1,2, till 3, a circuit finished.
But we can still optimize it. without pop 0,1,2 and add them again, we can just apply the structure Deque which can add and pop on both sides. Since the path will be a circuit, there's no need to delete any point, just add point on different sides, finally the points in de deque will combine a path.
So we start from 0, if the sum_gas will be >=0, we add next point on right side, otherwise, we add point on the left side.
Java
public class Solution {
public int canCompleteCircuit(int[] gas, int[] cost){
//corner
if ( gas == null || cost == null || gas.length != cost.length )
return -1;
//core
int start = gas.length - 1; //用two pointer模拟deque,并不需要建立deque
int end = 0;
int gasLeftSum = gas[start] - cost[start];
while ( start > end ){
if ( gasLeftSum >= 0 ){ //end开始并为加进来,所以先加,再右移
gasLeftSum += gas[end] - cost[end];
end++;
}else{
start--;
gasLeftSum += gas[start] - cost[start]; //start最开始已经被加上了,所以先左移,再加油
}
}
return gasLeftSum >= 0 ? start : -1;
}
}
- Android深入理解JNI(二)类型转换、方法签名和JNIEnv
- 探讨通过Feign配合Hystrix进行调用时异常的处理
- 小窗播放视频的原理和实现(上)
- 一种Android App在Native层动态加载so库的方案
- java的双缓冲技术
- application之OnLowMemory()和 OnTrimMemory(level)讲解
- React Native组件(一)组件的生命周期
- Spring Cloud构建微服务架构:服务消费(基础)【Dalston版】
- Android解析ClassLoader(一)Java中的ClassLoader
- Android学习笔记(一)之仿正点闹钟时间齿轮滑动的效果
- Android解析WindowManager(三)Window的添加过程
- Spring Cloud构建微服务架构:服务消费(Ribbon)【Dalston版】
- Android解析WindowManager(一)WindowManager体系
- ios9 http请求失败的问题
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 快速建站“新玩具”—glitch.me
- 踩坑记 | Flutter升级影响了NestedScrollView?
- Android | xml和view的那些事
- Android | 资源冲突覆盖的一些思考
- 如何用脚本自动转化,一个protobuf文件到json格式
- 聊聊dubbo-go的forkingCluster
- 还在用 map[string]interface{} 处理 JSON?告诉你一个更高效的方法——jsonvalue
- 聊聊dubbo-go的failsafeCluster
- 【HDFS】distcp报错Check0sum mismatch
- ffmpeg转换多媒体文件,真香
- 静态库与动态库的那些事
- 云服务器网络延迟与丢包问题定位(mtr工具)
- Spark UDF1 输入复杂结构
- Qt音视频开发6-ffmpeg解码处理
- MySQL 百万级数据量分页查询方法及其优化