Leetcode135. 分发糖果

LeetCode135——分发糖果 我的LeetCode代码仓:https://github.com/617076674/LeetCode 原题链接:https://leetcode-cn.com/problems/candy/description/ 题目描述: 知识点:贪心算法 思路:贪心算法 初始化每个人分配的糖果数量都是1。 (1)从前往后遍历ratings数组,如果发现当前位置的值比前一个位置的值要大,需要... 阅读详情

Every day a leetcode

题目来源:135. 分发糖果

解法1:贪心

首先把所有孩子的糖果数初始化为1。

从左往右遍历一遍,如果右边孩子的评分比左边的高,则右边孩子的糖果数更新为左边孩子的糖果数加1。

再从右往左遍历一遍,如果左边孩子的评分比右边的高,且左边孩子当前的糖果数不大于右边孩子的糖果数,则左边孩子的糖果数更新为右边孩子的糖果数加1。

代码:

#include <iostream>
using namespace std;

int candy(int *ratings, int ratingsSize);

int main()
{
    int n;
    cin >> n;
    int a[n];
    for (int i = 0; i < n; i++)
        cin >> a[i];
    cout << candy(a, n) << endl;

    system("pause");
    return 0;
}

int candy(int *ratings, int ratingsSize)
{
    int n = ratingsSize;
    int candy[n];

    for (int i = 0; i < n; i++) // 每个孩子至少分配到1个糖果
    {
        candy[i] = 1;
        // cout << candy[i] << " ";
    }
    // cout << endl;
    // 从左往右遍历一遍,如果右边孩子的评分比左边的高,则右边孩子的糖果数更新为左边孩子的糖果数加1
    for (int i = 0; i < n - 1; i++)
        if (ratings[i] < ratings[i + 1])
            candy[i + 1] = candy[i] + 1;
    // 从右往左遍历一遍,如果左边孩子的评分比右边的高,且左边孩子当前的糖果数不大于右边孩子的糖果数,
    // 则左边孩子的糖果数更新为右边孩子的糖果数加1
    for (int i = n - 1; i > 0; i--)
        if (ratings[i - 1] > ratings[i] && candy[i - 1] <= candy[i])
            candy[i - 1] = candy[i] + 1;
    // 统计糖果总数
    int sum = 0;
    for (int i = 0; i < n; i++)
        sum += candy[i];
    return sum;
}


结果:

在这里插入图片描述

复杂度分析:

时间复杂度:O(n),其中n是孩子的数量。我们需要遍历两次数组以分别计算满足左规则或右规则的最少糖果数量。

空间复杂度:O(n),其中n是孩子的数量。我们需要candy数组储存糖果数。

解法2:常数空间遍历

注意到糖果总是尽量少给,且从1开始累计,每次要么比相邻的同学多给一个,要么重新置为1。

依据此规则,我们可以画出下图:

在这里插入图片描述

其中相同颜色的柱状图的高度总恰好为1,2,3,…。

而高度也不一定一定是升序,也可能是…,3,2,1。

注意到在上图中,对于第三个同学,他既可以被认为是属于绿色的升序部分,也可以被认为是属于蓝色的降序部分。因为他同时比两边的同学评分更高。我们对序列稍作修改:

在这里插入图片描述

注意到右边的升序部分变长了,使得第三个同学不得不被分配4个糖果。

依据前面总结的规律,我们可以提出本题的解法。我们从左到右枚举每一个同学,记前一个同学分得的糖果数量为pre:

如果当前同学比上一个同学评分高,说明我们就在最近的递增序列中,直接分配给该同学pre+1个糖果

否则我们就在一个递减序列中,我们直接分配给当前同学一个糖果,并把该同学所在的递减序列中所有的同学都再多分配一个糖果,以保证糖果数量还是满足条件。

我们无需显式地额外分配糖果,只需要记录当前的递减序列长度,即可知道需要额外分配的糖果数量。

同时注意当当前的递减序列长度和上一个递增序列等长时,需要把最近的递增序列的最后一个同学也并进递减序列中。

这样,我们只要记录当前递减序列的长度dec,最近的递增序列的长度inc和前一个同学分得的糖果数量pre即可。

代码:

int candy(int* ratings, int ratingsSize) {
    int ret = 1;
    int inc = 1, dec = 0, pre = 1;
    for (int i = 1; i < ratingsSize; i++) {
        if (ratings[i] >= ratings[i - 1]) {
            dec = 0;
            pre = ratings[i] == ratings[i - 1] ? 1 : pre + 1;
            ret += pre;
            inc = pre;
        } else {
            dec++;
            if (dec == inc) {
                dec++;
            }
            ret += dec;
            pre = 1;
        }
    }
    return ret;
}

复杂度分析:

时间复杂度:O(n),其中n是孩子的数量。我们需要遍历1次数组。

空间复杂度:O(1)。我们只需要常数的空间保存若干变量。

分发糖果力扣--135 比较右边的大于左边的情况 ratings【i】>ratings[i+1],因为这里有i+1,所以遍历的时候是从下标为ratings.length-2的位置开始的。所以先从前往后,把下标为0的糖果数目先定为1,比较右边的大于左边的情况 ratings【i】>ratings[i-1],因为这里有i-1,所以遍历的时候是从下标为1的位置开始的。糖果: 1 2 1 2 1 1 1。第三个孩子只得到 1 颗糖果,这满足题面中的两个条件。 阅读详情

相关推荐

【困难】力扣算法题解析LeetCode135:分发糖果

题目要求为一排孩子分发糖果,满足每个孩子至少1颗糖,且相邻孩子中评分更高的必须获得更多糖果。通过两次遍历(左到右和右到左)确保同时满足左右相邻规则,最终计算最少糖果数。Java实现中初始化每人1颗糖,先处理左规则(若右孩子评分更高则糖果数+1),再处理右规则(取左右规则中的较大值)。时间复杂度O(n),空间复杂度O(n)。示例输入[1,0,2]输出5,[1,2,2]输出4。完整代码及调试信息可点击底部名片获取。

ylumwd的博客 387

leetcode力扣——135.分发糖果

从左向右看: 1,1,2,3,4,1,1,1,2,1。从右向左看: 2,1,1,1,2,1,2,1,2,1。从左向右看: 1,1,2,3,4,1,1,1,2,1。从右向左看: 2,1,1,1,2,1,2,1,2,1。小朋友的分数:2,1,3,4,5,2,2,1,3,0。得到的糖果数:2,1,2,3,4,1,2,1,2,1。小朋友的分数:2,1,3,4,5,2,2,1,3,0。小朋友的分数:2,1,3,4,5,2,2,1,3,0。得到的糖果数:2,1,2,3,4,1,2,1,2,1。

Xiaoyuan_he的博客 1067

一篇教你杰理63系列蓝牙双设备主从连接传输数据过程及配置

首先打开632sdk的app_config.h文件,将宏CONFIG_APP_SPP_LE写0,将宏CONFIG_APP_MULTI写1,对应的CONFIG_BT_GATT_CLIENT_NUM写1代表我只连接一个主机设备。属性都可以修改为自己想要的属性,然后关掉文件,双击gatt_inc_generator.exe文件运行,就会自动弹出生成/更新后的gatt_profile_cfg.h文件,然后里面就是我们代码里面所需要的配置,都是十六进制表示,找到我们刚刚添加的服务属性配置,复制到代码里面去。

xiaolizaixian的博客 1379

135. 分发糖果【 力扣(LeetCode) 】

n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目。

yyh520025的博客 1459

Ubuntu开发环境配置——持续更新

本文简要介绍了Ubuntu下的开发环境配置流程和问题分析与解决,更多内容持续更新中。

m0_53365889的博客 2225

如何在Android上使用OpenCV进行摄像头标定

如何在Android上使用OpenCV进行摄像头标定,我们这里使用官方一个例程,其实并不难,只是网上的资料少了而已。相机标定是计算机视觉工作的前提,为了确定相机矩阵和畸变参数。

花草的博客 3440

135. 分发糖果(力扣LeetCode)

这在leetcode上是一道困难的题目,其难点就在于贪心的策略,如果在考虑局部的时候想两边兼顾,就会顾此失彼。一次是从左到右遍历,只比较右边孩子评分比左边大的情况。一次是从右到左遍历,只比较左边孩子评分比右边大的情况。这样从局部最优推出了全局最优,即:相邻的孩子中,评分高的孩子获得更多的糖果。

m0_73841621的博客 1082

Ubuntu Server 22.04.5系统安装教程

该教程主要是演示在服务器上安装Ubuntu server 22.04系统的详细步骤,主要包含,安装系统前的准备(镜像的下载,启动盘的制作),安装系统时的语言选择,网络设置,切换镜像源(可根据实际需求来配置,本文使用清华镜像源),手动分区,用户设置,ssh服务安装等。以上就是关于Ubuntu Server 22.04系统安装的详细过程。

逆水行舟,不进则退。 7771

LeetCode135_分发糖果

分***糖果

Haolin_Liu的博客 856

PICO4 VR开发调试神器:用Live Preview Plugin实现电脑串流,告别反复打包烧录的繁琐流程

本文详细介绍了PICO4 VR开发中如何使用Live Preview Plugin实现电脑串流,显著提升开发效率。通过实时预览和调试功能,开发者可以避免反复打包烧录的繁琐流程,特别适用于Unity环境下的VR应用开发。文章涵盖环境配置、连接设置、实时调试技巧及性能优化方案,是PICO4开发者的必备指南。

weixin_34110970的博客 419

Windows 10/11下R与RStudio最新版安装避坑指南(含镜像加速配置)

本文提供了Windows 10/11系统下R与RStudio最新版的详细安装指南,包含镜像加速配置和常见问题解决方案。通过分步教程帮助用户避开安装陷阱,优化开发环境设置,特别适合国内用户快速搭建高效的数据分析平台。

weixin_29065959的博客 1008

LeetCode135分发糖果

n个孩子站成一排。给你一个整数数组ratings表示每个孩子的评分。1请你给每个孩子分发糖果,计算并返回需要准备的。5你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。

liliyexing的博客 731

基于 高斯过程回归(Gaussian Process Regression, GPR) 的 时间序列区间预测 的 MATLAB 示例代码

基于 高斯过程回归(Gaussian Process Regression, GPR) 的 时间序列区间预测 的 MATLAB 示例代码

算法如诗的博客 155

力扣Leetcode之Java解题135分发糖果

力扣java解题135分发糖果

小李子Lee 268

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

LeetCode 力扣 135. 分发糖果

题目描述(困难难度) 给 N 个小朋友分糖,每个人至少有一颗糖。并且有一个 rating 数组,如果小朋友的 rating比它旁边小朋友的 rating 大(不包括等于),那么他必须要比对应小朋友的糖多。问至少需要分配多少颗糖。 用 - 表示糖,举几个例子。 1 0 2 - - - - - 总共就需要 5 颗糖。 1 2 2 - - - - 总共就需要 4 颗糖。 解法一 根据题目,首...

wind_liang的博客 1157

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

LeetCode 135. 分发糖果

LeetCode 135. 分发糖果 解题思路和代码 我们可以举一个比样例稍微好一点的例子[7,8,4,2,1,3,5,9,7] 。 首先可以想到第一种思路: 我们先定义一个数组candies,这个数组存放着每个人最终获得的糖果。 接着我们找到数组的最小值及其下标定义为sym。如果是第一次遍历,则直接令candies[sym]=1,因为每一位小朋友至少要有一个糖果。在例子中这个最小值是1,sym...

huyifan1的博客 348

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

力扣135-分发糖果(接近双100%的 Java 版详细题解)

力扣135-分发糖果(接近双100%的 Java 版详细题解)

ItDaChuang的博客 465

【leetcode】135. 分发糖果

🚅【leetcode】135. 分发糖果🚀题目💥leetcode代码模板🚀思路💻代码 🚀题目 leetcode原题链接 n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求,给这些孩子分发糖果: 每个孩子至少分配到 1 个糖果。 相邻两个孩子评分更高的孩子会获得更多的糖果。 请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。 示例 1: 输入:ratings = [1,0,2] 输出:5 解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、

laplacepoisson的博客 406

LeetCode135 && LeetCode1103:分发糖果

博主将 LeetCode135 和 LeetCode1103 两道题放在一起,虽然都是分糖果,但是思路却完全不一样。仅供借鉴。 目录 一、题目 二、示例 三、思路 四、代码 一、题目 LeetCode135:分发糖果 老师想给孩子们分发糖果,有 N个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。 你需要按照以下要求,帮助老师给这些孩子分发糖果: 每个孩子至少分配到 1 个糖果。 评分更高的孩子必须比他两侧的邻位孩子获得更多的糖果。 那么这样下来,老师至少需要准备多少颗.

D77的博客 416

Leetcode(135)——分发糖果

分发糖果

KCDCY的博客 1818

LeetCode第135题_分发糖果

n个孩子站成一排。给你一个整数数组ratings表示每个孩子的评分。请你给每个孩子分发糖果,计算并返回需要准备的。

qq_40263592的博客 1097

LeetCode 135 分发糖果(Candy)

LeetCode 135 分发糖果(Candy) 135. 分发糖果 题目的????:1149 题目的????:173 1、题目描述 老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。 你需要按照以下要求,帮助老师给这些孩子分发糖果: 每个孩子至少分配到 1 个糖果。 相邻的孩子中,评分高的孩子必须获得更多的糖果。 那么这样下来,老师至少需要准备多少颗糖果呢? 示例 1: 输入: [1,0,2] 输出: 5 解释: 你可以分别给这三个孩子分发 2、1、2

botke的博客 1097

力扣135.分发糖果

用两次遍历解力扣135.分发糖果。

liuyuzhongcc的博客 257

「leetcode」135.分发糖果【贪心算法】详细图解

想要两边兼顾,就会顾此失彼

代码随想录 5198

Leetcode 135. 分发糖果(问题分解)

注意的是,此时nums并非全1的初始化状态,而是已经计算过的数组,若ratings[ i ] > ratings[ i+1 ]发生,而此时nums[ i ] > nums[ i+1 ]已经满足,则无需再次分配糖果,否则同理左遍历为nums[ i ]赋值。从左向右考虑ratings大于左侧,即ratings[ i ] > ratings[ i-1 ]情况,此时令 i 处的糖果数nums[ i ]直接赋值为nums[ i-1 ] + 1即可满足条件。

ooold_six的博客 693
上一篇: Leetcode455. 分发饼干
下一篇: Leetcode435. 无重叠区间
UestcXiye
博客等级 码龄8年 9032粉丝 1306原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

UestcXiye

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

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

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

打赏作者

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

抵扣说明:

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

余额充值