题意:

image.png

解题思路:

  1. 思路:
  2. 1. 暴力解法O(n2):枚举每一个加油站作为起点,判断该起点的油能否到下一个加油站,如果不能则跳到下一个加油站作为起点,出发,直到环绕一周。
  3. 2. (优化) O(n):暂定i~j加油站能成功,但是i不能到达j+1加油站,则i~j中的所有加油站必然都不能到达j+1加油站,所以可以直接跳过j,从下一个j+1加油站作为起点,继续向下一个出发;

PHP代码实现:

  1. class Solution {
  2. /**
  3. * @param Integer[] $gas
  4. * @param Integer[] $cost
  5. * @return Integer
  6. */
  7. //暴力
  8. function canCompleteCircuit($gas, $cost) {
  9. $n = count($gas);
  10. for ($i = 0; $i < $n; $i++) {
  11. $tank = 0;
  12. for ($j = $i; $j < $i + $n; $j++) {
  13. $k = $j % $n;
  14. $tank += $gas[$k] - $cost[$k];
  15. if ($tank < 0) break;
  16. }
  17. if ($tank >= 0) return $i;
  18. }
  19. return -1;
  20. }
  21. //暴力优化
  22. function canCompleteCircuitSkip($gas, $cost) {
  23. $n = count($gas);
  24. $j = 0;
  25. for ($i = 0; $i < $n; $i = $j + 1) {
  26. $tank = 0;
  27. for ($j = $i; $j < $i + $n; $j++) {
  28. $k = $j % $n;
  29. $tank += $gas[$k] - $cost[$k];
  30. if ($tank < 0) break;
  31. }
  32. if ($tank >= 0) return $i;
  33. }
  34. return -1;
  35. }
  36. //贪心算法
  37. function canCompleteCircuitGreedy($gas, $cost) {
  38. $total = 0;
  39. $sum = 0;
  40. $start = 0;
  41. for ($i = 0; $i < count($gas); $i++) {
  42. $total += $gas[$i] - $cost[$i];
  43. $sum += $gas[$i] - $cost[$i];
  44. // echo $total.'&&&&&'.$sum;echo PHP_EOL;
  45. if ($sum < 0) {
  46. $start = $i + 1;
  47. $sum = 0;
  48. }
  49. }
  50. return ($total < 0) ? -1 : $start;
  51. }
  52. }

GO代码实现:

  1. func canCompleteCircuit(gas []int, cost []int) int {
  2. n := len(gas)
  3. for i := 0; i < n; i++ {
  4. tank := 0
  5. for j := i; j < i + n; j++ {
  6. k := j % n
  7. tank += gas[k] - cost[k]
  8. if tank < 0 {
  9. break
  10. }
  11. }
  12. if tank >= 0 {
  13. return i
  14. }
  15. }
  16. return -1
  17. }