LeetCode面试题Day7|LeetCode135 分发糖果、LeetCode42 接雨水

题目1:

指路:

. - 力扣(LeetCode)135 分发糖果

思路与分析:

给n个孩子按照评分给糖果,要求有二,其一为每个孩子最少有一颗糖果;其二为相邻孩子评分更高的糖果越多。那么在这里第一个条件没有异议,直接初始化一个结果数组初始化为n个1即可。那么接下来就是对比相邻孩子之间的评分并设置糖果值。在这里有一个需要思考的地方,拿给出的exampl1来讲,[1, 0, 2],对于左边两个孩子的评分来说,左1孩子评分比中间的孩子高,得到的糖果数也应该比中间的孩子多,而对于右边的两个孩子说,右边的孩子评分比中间的孩子高,得到的糖果数也应该比中间的孩子多。那么按照初始化为1的糖果数来看,最初三者糖果数皆为1,而左边孩子的糖果为2,右边孩子多一个也应该是2。那么总数就是5。那么再多几个孩子,例如[1, 2, 4, 3, 6, 5],首先,初始化的糖果集无异,[1, 1, 1, 1, 1, 1],那么因为(从左往右)第二个孩子的评分高于第一个,而第三个孩子的评分多于第二个,所以前三个孩子的糖果数应该是:第三个>第二个>第一个。而从第四个开始,因为其评分低于第三个,所以第四个孩子的糖果数理应少于第三个。那么这里就引发了左右不统一。接下来尝试解决左右不统一的问题。我们可以将评分分为两部分,左边>右边和右边大于左边,从前往后遍历时,当后者评分大于前者评分时,后者的糖果数也应该比前者的糖果数多一个(求的是最少的糖果数)。同样,从后往前当前者的评分大于后者评分时,这个孩子的糖果数为右边孩子的糖果数+1。当其顺序遍历得到的糖果数大于倒序遍历得到的糖果数时保留原糖果数。最后得到糖果集的总和即为最少需要准备的糖果数。

代码:

class Solution {
public:
    int candy(vector<int>& ratings) {
    int n = ratings.size();
    int ans = 0;
    vector<int> candies(n, 1);  // 最终糖果集
    for (int i = 1; i < n; i++) {
        if (ratings[i] > ratings[i - 1]) {  
            candies[i] = candies[i - 1] + 1;
        }
    }
    for (int i = n - 2; i >= 0; i--) {
        if (ratings[i] > ratings[i + 1]) {
            candies[i] = max(candies[i], candies[i + 1] + 1);
        }
    }
    for (int i = 0; i < n; i++) {
        ans += candies[i];
    }
    return ans;
    }
};

题目2:

指路:

. - 力扣(LeetCode)42 接雨水

思路与分析:

经典接雨水,那么我们讲接雨水的条件是两边的板高度大于中间,且短板效应接到的雨水高度以较低的板为主。那么首先要找出左边界的最大值和右边界的最大值。最后因为其宽度都为1,最正确的应该是长度乘宽度。

代码:

class Solution {
public:
    int trap(vector<int>& height) {
    int hsum = 0;
    int n = height.size();
    if (n == 0) return 0;
    vector<int> leftMax(n, 0);
    leftMax[0] = height[0];
    for (int i = 1; i < n; i++) {
        leftMax[i] = max(leftMax[i - 1], height[i]);
    }
    vector<int> rightMax(n, 0);
    rightMax[n - 1] = height[n - 1];
    for (int i = n - 2; i >= 0; i--) {
        rightMax[i] = max(rightMax[i + 1], height[i]);
    }
    for (int i = 0; i < n; i++) {
            hsum += min(leftMax[i], rightMax[i]) - height[i];
    }
    return hsum;
    }
};

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C.G.道枝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值