• LeetCode加油站(贪心算法/暴力,分析其时间和空间复杂度)



    题目描述

     一.原本暴力算法

    最初的想法是:先比较gas数组和cost数组的大小,找到可以作为起始点的站点(因为如果你起始点的油还不能到达下一个站点,就不能作为起始点)。当找到过后,再去依次顺序跑一圈,如果剩余的油为负数,再去寻找下一个满足条件的起始站点。

    1. class Solution {
    2. public:
    3. int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
    4. int index = -1; //定义初始起点
    5. int left = 0; //定义剩余油量
    6. bool flag = false;
    7. int n = gas.size();
    8. //寻找起始位置
    9. for(int i = 0;i
    10. {
    11. if(gas[i] < cost[i])
    12. {
    13. continue;
    14. }
    15. else{
    16. index = i;
    17. int j = index;
    18. int count = 0;
    19. cout<<"index="<
    20. while(true)
    21. {
    22. j = j%n;
    23. cout<<"j="<
    24. if(left < 0)
    25. {
    26. left = 0;
    27. break;
    28. }
    29. if(count == n)
    30. {
    31. flag = true;
    32. return index;
    33. }
    34. left = left + gas[j] - cost[j];
    35. cout<<"left="<
    36. count++;
    37. j++;
    38. }
    39. }
    40. }
    41. //判断
    42. if(flag)
    43. {
    44. return index;
    45. }else{
    46. return -1;
    47. }
    48. }
    49. };

    但是代码最后超时了!!

    时间复杂度是O(N^2) 因为循环遍历寻找起始站点,找到过后再去循环遍历走一圈是O(N^2)的时间复杂度!

    巧妙思路算法二能通过的

    转子大佬的代码。

    • 情况一:如果gas的总和小于cost总和,那么无论从哪里出发,一定是跑不了一圈的

    • 情况二:rest[i] = gas[i]-cost[i]为一天剩下的油,i从0开始计算累加到最后一站,如果累加没有出现负数,说明从0出发,油就没有断过,那么0就是起点。

    • 情况三:如果累加的最小值是负数,汽车就要从非0节点出发,从后向前,看哪个节点能把这个负数填平,能把这个负数填平的节点就是出发节点。

      1. class Solution {
      2. public:
      3. int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
      4. int curSum = 0;
      5. int min = INT_MAX; // 从起点出发,油箱里的油量最小值
      6. for (int i = 0; i < gas.size(); i++) {
      7. int rest = gas[i] - cost[i];
      8. curSum += rest;
      9. if (curSum < min) {
      10. min = curSum;
      11. }
      12. }
      13. if (curSum < 0) return -1; // 情况1
      14. if (min >= 0) return 0; // 情况2
      15. // 情况3
      16. for (int i = gas.size() - 1; i >= 0; i--) {
      17. int rest = gas[i] - cost[i];
      18. min += rest;
      19. if (min >= 0) {
      20. return i;
      21. }
      22. }
      23. return -1;
      24. }
      25. };

      在这里时间复杂度O(N)

    • 空间复杂度O(1)没有开辟新的空间

    二.贪心算法

    每个加油站的剩余量rest[i]为gas[i] - cost[i]。

    i从0开始累加rest[i],和记为curSum,一旦curSum小于零,说明[0, i]区间都不能作为起始位置,因为这个区间选择任何一个位置作为起点,到i这里都会断油,那么起始位置从i+1算起,再从0计算curSum。

    1. class Solution {
    2. public:
    3. int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
    4. int curSum = 0;
    5. int totalSum = 0;
    6. int start = 0;
    7. for (int i = 0; i < gas.size(); i++) {
    8. curSum += gas[i] - cost[i];
    9. totalSum += gas[i] - cost[i];
    10. if (curSum < 0) { // 当前累加rest[i]和 curSum一旦小于0
    11. start = i + 1; // 起始位置更新为i+1
    12. curSum = 0; // curSum从0开始
    13. }
    14. }
    15. if (totalSum < 0) return -1; // 说明怎么走都不可能跑一圈了
    16. return start;
    17. }
    18. };

    时间复杂度O(N) 

    转载于代码随想录,大佬的算法

  • 相关阅读:
    最新win11配置cuda以及cudnn补丁教程
    三十九、Fluent时间步长的估算与库朗数
    Java-Atomic原子操作类详解及源码分析,Java原子操作类进阶,LongAdder源码分析
    PROFINET主站转ETHERCAT协议网关
    九、数组的扩展(扩展运算符)
    Hive面试题系列第六题-互为好友问题
    VMware+Ubuntu安装过程,含秘钥
    [USB 设备_1]-使用 H2testw 1.4 或其她工具检测新买的朗科 U 盘读写速度及是否是扩容盘
    dc-dc线性降压恒流驱动,40V降压恒流驱动芯片
    基于R语言的DICE模型实践丨农田生态系统温室气体排放模拟
  • 原文地址:https://blog.csdn.net/m0_74301606/article/details/140309695