Skip to content

Commit 03eaac8

Browse files
author
DmrfCoder
committed
加油站问题-gas-station
1 parent e7e5ab2 commit 03eaac8

32 files changed

+193
-0
lines changed

LeetCode/Doc/加油站问题.md

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# 加油站问题(gas-station)
2+
3+
<center>知识点:贪心</center>
4+
5+
## 题目描述
6+
7+
There are N gas stations along a circular route, where the amount of gas at station i is gas[i].
8+
9+
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.
10+
11+
Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.
12+
13+
Note:
14+
The solution is guaranteed to be unique.
15+
16+
在一条循环路线上有N个加油站,索引为i的加油站具有的油量为gas[i]
17+
你有一辆具有不限容量油箱的小汽车,并且这辆车从第i个加油站到第i+1个加油站耗费的油量是cost[i],初始的时候你的小汽车的油箱里面没有油,你需要寻找一个站点作为起点。
18+
如果从某个起点出发可以保证你开着你的车绕着赛道走一圈,则返回起点的加油站下标,否则返回-1
19+
返回起点加油站的下标。
20+
21+
注意:给出的实例可以保证解决方案是唯一的。
22+
23+
24+
25+
26+
## 解题思路
27+
28+
贪心的思路,计算从每一站出发,到达下一站后车里还能剩余的油,然后按照剩余油的多少进行排序,从剩余油最多的站出发,进行模拟。
29+
30+
31+
## 代码
32+
核心代码:
33+
```java
34+
public int canCompleteCircuit(int[] gas, int[] cost) {
35+
36+
//remaining为二维数组,remaing[index][0]代表车从第index出发到达index+1站后里面可以剩余的油,
37+
// remaing[index][1]=index,因为后面要对remaing按照remaing[index][0]即剩余的油量排序,
38+
// 所以要把原始的索引记录下来,排完序后直接从remaing[index][0]最大的值对应的remain[index][1]处开始开车即可
39+
int[][] remaining = new int[gas.length][2];
40+
41+
//gas[i]---->gas[i+1] cost[i],计算remaining
42+
for (int index = 0; index < gas.length; index++) {
43+
remaining[index][0] = gas[index] - cost[index];
44+
remaining[index][1] = index;
45+
}
46+
47+
//按照remaining[index][0]对remaing进行排序
48+
QuickSort(remaining, gas.length);
49+
50+
//由于上面排完序是降序,所以这里从后往前遍历
51+
for (int index = gas.length - 1; index >= 0; index--) {
52+
//如果剩余的油大于等于0,说明油足够到达下一站
53+
if (remaining[index][0] >= 0) {
54+
if (helper(gas, cost, remaining[index][1])) {
55+
return remaining[index][1];
56+
}
57+
} else {
58+
return -1;
59+
}
60+
}
61+
62+
63+
return -1;
64+
}
65+
66+
//模拟从第startIndex站出发,看能不能走完全程
67+
boolean helper(int[] gas, int[] cost, int startIndex) {
68+
int count = 0;
69+
int curGas = 0;
70+
for (int index = startIndex; count <= gas.length; count++, index = (index + 1) % gas.length) {
71+
curGas += gas[index];
72+
if (curGas >= cost[index]) {
73+
curGas -= cost[index];
74+
} else {
75+
return false;
76+
}
77+
}
78+
79+
return true;
80+
}
81+
82+
```
83+
84+
[完整代码](../src/seventeen/Solution.java)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

LeetCode/src/samplepackage/Solution.java

+5
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,9 @@
55
* @date 2019/4/10
66
*/
77
public class Solution {
8+
9+
public static void main(String[] args){
10+
Solution solution=new Solution();
11+
12+
}
813
}

LeetCode/src/seventeen/Solution.java

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package seventeen;
2+
3+
/**
4+
* @author dmrfcoder
5+
* @date 2019/4/10
6+
*/
7+
public class Solution {
8+
public int canCompleteCircuit(int[] gas, int[] cost) {
9+
10+
//remaining为二维数组,remaing[index][0]代表车从第index出发到达index+1站后里面可以剩余的油,
11+
// remaing[index][1]=index,因为后面要对remaing按照remaing[index][0]即剩余的油量排序,
12+
// 所以要把原始的索引记录下来,排完序后直接从remaing[index][0]最大的值对应的remain[index][1]处开始开车即可
13+
int[][] remaining = new int[gas.length][2];
14+
15+
//gas[i]---->gas[i+1] cost[i],计算remaining
16+
for (int index = 0; index < gas.length; index++) {
17+
remaining[index][0] = gas[index] - cost[index];
18+
remaining[index][1] = index;
19+
}
20+
21+
//按照remaining[index][0]对remaing进行排序
22+
QuickSort(remaining, gas.length);
23+
24+
//由于上面排完序是降序,所以这里从后往前遍历
25+
for (int index = gas.length - 1; index >= 0; index--) {
26+
//如果剩余的油大于等于0,说明油足够到达下一站
27+
if (remaining[index][0] >= 0) {
28+
if (helper(gas, cost, remaining[index][1])) {
29+
return remaining[index][1];
30+
}
31+
} else {
32+
return -1;
33+
}
34+
}
35+
36+
37+
return -1;
38+
}
39+
40+
//模拟从第startIndex站出发,看能不能走完全程
41+
boolean helper(int[] gas, int[] cost, int startIndex) {
42+
int count = 0;
43+
int curGas = 0;
44+
for (int index = startIndex; count <= gas.length; count++, index = (index + 1) % gas.length) {
45+
curGas += gas[index];
46+
if (curGas >= cost[index]) {
47+
curGas -= cost[index];
48+
} else {
49+
return false;
50+
}
51+
}
52+
53+
return true;
54+
}
55+
56+
void QuickSort(int[][] v, int length) {
57+
QSort(v, 0, length - 1);
58+
}
59+
60+
void QSort(int[][] v, int low, int high) {
61+
62+
if (low >= high) {
63+
return;
64+
}
65+
int t = Partition(v, low, high);
66+
QSort(v, low, t - 1);
67+
QSort(v, t + 1, high);
68+
}
69+
70+
int Partition(int[][] v, int low, int high) {
71+
int pivotkey;
72+
pivotkey = v[low][0];
73+
74+
while (low < high) {
75+
while (low < high && v[high][0] >= pivotkey) {
76+
--high;
77+
}
78+
int[] t;
79+
t = v[low];
80+
v[low] = v[high];
81+
v[high] = t;
82+
83+
while (low < high && v[low][0] <= pivotkey) {
84+
++low;
85+
}
86+
t = v[low];
87+
v[low] = v[high];
88+
v[high] = t;
89+
}
90+
91+
return low;
92+
}
93+
94+
95+
public static void main(String[] args) {
96+
Solution solution = new Solution();
97+
int[] gas = {2, 3, 1};
98+
int[] cost = {3, 1, 2};
99+
int index = solution.canCompleteCircuit(gas, cost);
100+
System.out.println("startIndex is: " + index);
101+
102+
}
103+
}

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@
158158
- [single-number(出现一次的数)](./LeetCode/Doc/出现一次的数.md)
159159
- [**single-number-ii(出现一次的数2)**](./LeetCode/Doc/出现一次的数2.md)
160160
- [candy(糖果问题)](./LeetCode/Doc/糖果问题.md)
161+
- [Gas-station(加油站问题)](./LeetCode/Doc/加油站问题.md)
161162

162163

163164

0 commit comments

Comments
 (0)