代码随想录算法训练营:29/60

非科班学习算法day29 | LeetCode134:加油站 ,Leetcode135:分发糖果 ,Leetcode860:柠檬水找零 


介绍

包含LC的两道题目,还有相应概念的补充。

相关图解和更多版本:

代码随想录 (programmercarl.com)https://programmercarl.com/#%E6%9C%AC%E7%AB%99%E8%83%8C%E6%99%AF


  

一、LeetCode题目

1.LeetCode134:加油站 

题目链接:134. 加油站 - 力扣(LeetCode)

题目解析

       这里很容易被示例的做法干扰,实际上,我们需要的就是别对两个数组,到达一个位置(i)对应的需要加上gas(i)减去cost(i),这就我们需要比对的。这里先说一种之前有局限性的思路,先对两个数组相减,构造新的数组,如果数组元素为负数表示到达不了下一位,那么继续遍历,找到第一个不为负数的位置为初始位置,并且控制总和为负数的话返回-1,这样的做法最大的问题就在于我没有意识到,加油的过程也是需要一个初始量累计的,所以我不能单纯比较一个位置为负数就跳过这个位置,而应该是用cur变量维护start的位置,如果cur在累加的过程中变为负数,那么就重置cur并且将返回的start向后加一位。

 c++代码如下:

class Solution {
public:
    //gas是加的,cost是减的
    //建立差值数组,如果数组和是负数,那么不可能有解,如果大于等于则有唯一解
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) 
    {
        int tolsum = 0;
        int cursum = 0;
        int start = 0;
        vector<int> nd = vector<int>(gas.size(),0);
        for(int i = 0; i<gas.size();i++)
        {
            nd[i] = gas[i] - cost[i];
            tolsum+=nd[i];
            cursum+=nd[i];
            if(cursum<0)
            {
                start = i+1;
                cursum = 0;
            }
        }
        if(tolsum<0) return -1;
        return start;

    }
};

注意点1:这里可能会疑惑start超出最后一位怎么办,实际上,当cur超出最后一位的时候,并没有影响,不会访问空指针;而且关于最后的返回有tolsum控制,如果start超出,直接就返回-1了。注意!这里整个循环已经完成了一轮遍历,只不过遍历是从头到尾的。

 2.Leetcode135:分发糖果 

题目链接:135. 分发糖果 - 力扣(LeetCode)

题目解析

       第一次做就是中了圈套,总想一次就确定好糖果的数量,这就导致条件特别多,很容易混乱,这里就使用了一种非常常用的方法,两个方向分别遍历,去比较一个元素的左边和右边元素的关系,同时维护糖果数组,这样就可以实时更正。

        这里有一个问题就是为什么需要两个方向,因为在比较右边元素的时候,和左边一样,有一个累计的过程,如果从左边遍历比较右边的元素,就没法实时更新下一个元素的信息。

 C++代码如下: 

class Solution {
public:
    // 不能顾此失彼,分为两边去比对孩子
    int candy(vector<int>& ratings) {
        // 创建需要维护的糖果数组
        vector<int> candys = vector<int>(ratings.size(), 1);
        // 想象排队过程,先和左边的孩子比是大是小
        for (int i = 1; i < ratings.size(); ++i) {
            // 维护数组
            // 左边小-加糖果
            if (ratings[i] > ratings[i - 1]) {
                candys[i] = candys[i - 1] + 1;
            }
            // 左边大-重置糖果
            else {
                candys[i] = 1;
            }
        }
        // 比对右边孩子是大是小
        for (int i = ratings.size() - 2; i >= 0; --i) {
            // 在之前的基础上维护数组
            // 右边小-加糖果
            if (ratings[i + 1] < ratings[i]) {
                candys[i] = max(candys[i], candys[i + 1] + 1);
            }
            // 右边大-无需操作
        }

        // 累计糖果
        int sum = 0;
        for (int i = 0; i < candys.size(); ++i) {
            sum += candys[i];
        }
        return sum;
    }
};

注意点1:这里初始化,将糖果数组全部初始化为1,因为题目要求孩子的最少糖果数是1。所以在左边遍历的过程中,遇到需要重置的糖果,也可以不写这个命令,因为已经做好了初始化。

注意点2:第二遍为什么右边大不需要维护数组,可以举一个数组作为例子,当前其实也是重置了糖果数量为1,但是要和之前的糖果数取一个大值,那么不就是当前的糖果数么,所以不需要处理。 

3.Leetcode860:柠檬水找零

题目链接:860. 柠檬水找零 - 力扣(LeetCode)

题目解析

       终于在贪心遇到一道爽题,这道题其实也就是模拟生活中找零的行为,但是需要注意的就是可能找不开零!那么我们的贪心策略就是尽可能找大的零(10)把灵活的5留着去找10的零,或者没有10的时候去找20的零。策略有了,就需要变量维护当前的钱的数量,这里没有维护20,因为20并不用于找零,只是作为判断条件来做找零行为。

C++代码如下:

class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        int m5 = 0;
        int m10 = 0;
        for (int i = 0; i < bills.size(); ++i) {
            if (bills[i] == 5)
                m5++;
            if (bills[i] == 10) {
                m10++;
                m5--;
            }

            if (bills[i] == 20) {
                if (m10 == 0) {
                    m5 -= 3;
                } else {
                    m10--;
                    m5--;
                }
            }

            if (m5 < 0)
                return false;
        }
        return true;
    }
};

总结


打卡第29天,坚持!!!

相关推荐

  1. 代码随想算法训练

    2024-07-10 17:50:01       57 阅读
  2. 代码随想算法训练

    2024-07-10 17:50:01       60 阅读
  3. 代码随想算法训练总结

    2024-07-10 17:50:01       47 阅读
  4. 代码随想算法训练总结

    2024-07-10 17:50:01       42 阅读
  5. 代码随想算法训练总结

    2024-07-10 17:50:01       41 阅读
  6. 代码随想训练

    2024-07-10 17:50:01       39 阅读
  7. 代码随想训练

    2024-07-10 17:50:01       41 阅读
  8. 代码随想训练

    2024-07-10 17:50:01       36 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-10 17:50:01       99 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-10 17:50:01       107 阅读
  3. 在Django里面运行非项目文件

    2024-07-10 17:50:01       90 阅读
  4. Python语言-面向对象

    2024-07-10 17:50:01       98 阅读

热门阅读

  1. Postman接口测试工具详解

    2024-07-10 17:50:01       24 阅读
  2. 逻辑回归的损失函数

    2024-07-10 17:50:01       25 阅读
  3. postman接口测试工具详解

    2024-07-10 17:50:01       27 阅读
  4. SQL语法(DQL):SELECT 多表查询之子查询

    2024-07-10 17:50:01       30 阅读
  5. 获取和设置Spring Cookie

    2024-07-10 17:50:01       26 阅读
  6. Spring——配置说明

    2024-07-10 17:50:01       26 阅读
  7. springboot中在filter中用threadlocal存放用户身份信息

    2024-07-10 17:50:01       32 阅读
  8. LDAP技术解析:打造安全、高效的企业数据架构

    2024-07-10 17:50:01       24 阅读
  9. android 替换设置-安全里面的指纹背景图片

    2024-07-10 17:50:01       29 阅读
  10. Node.js的应用场景

    2024-07-10 17:50:01       27 阅读