题目大意
一群小朋友站一排,然后每个小朋友有个rating值,现在让我们根据这个rating值来给每个小朋友分发糖果。但是分发的时候要按照以下规则:
- 每个小朋友至少要分发一个糖果
- 如果两个小朋友挨着,两个rating值一个大一个小,那么rating值大的那个小朋友必须比rating值小的那个小朋友分到更多的糖果
但是这里有一个恶心的地方,就是如果两个挨着的小朋友rating值一样,分到的糖果谁多谁少都无所谓(感觉题面出的很不切实际[doge])。
最后问你总共最少可以发多少颗糖果。
题目地址
思路
首先我们要排除一种特殊情况,如果大家的rating都是一样的,那么每个人都只能分到一颗糖果。
其次我们来贪心一下,在什么情况下,某个小朋友才会只被分到一颗糖果。
- 周围的小伙伴都不小于自己的时候,那你肯定只能得到一颗糖果
- 当你左边或者右边的小朋友跟你的rating值相同的时候(尤其是左右两边的都跟你一样的时候,肯定是1),有可能只被分到一颗糖果
那么什么时候小朋友可以被分到超过一颗糖果呢?
当发现一个严格递增或者严格递减的排列时,那么他们分到的糖果数也肯定是严格递增或者严格递减的。
然后就是代码实现的部分:
首先你先找出来周围的小朋友都大于自己的情况。
f = 1;
for (int i = N - 1; i >= 0; i--)
{
nums[i] = f;
if (i != 0 && ratings[i] < ratings[i - 1])
f = 0;
if (i != 0 && ratings[i] > ratings[i - 1])
f = 1;
}
f = 1;
for (int i = 0; i < N; i++)
{
nums[i] *= f;
if (i != N - 1 && ratings[i] < ratings[i + 1])
f = 0;
if (i != N - 1 && ratings[i] > ratings[i + 1])
f = 1;
}
第一个 for 循环是判断哪些小朋友位于递增的子数列里,因为他右边的第一个和他不一样的值如果比他大的话,那么他所处的位置肯定就是递增的,但是一定要注意最后一个位置,即使他左边的值比他大,他也有可能只被分到一颗糖果,一会给大家举个例子。
同理,第二个 for 循环是判断哪些小朋友处于递减的子数列里面,因为他左边的第一个跟他不一样的值如果比他大的话,就是处于递减的位置。同样也要注意第一个位置。
那么现在,同时处于递减和递增的位置(第一个和最后一个位置除外)的小朋友是不是肯定就只被分到了一颗糖果。
我们用下面的例子来举例。
r a t i n g s : [ 1 , 2 , 3 , 4 , 4 , 3 , 2 ] ratings: [1, 2, 3, 4, 4, 3, 2] ratings:[1,2,3,4,4,3,2]
如果我们按照上面的代码进行运行的话,那么第一次 for 循环执行过后,nums(用来存储每个人分到了多少颗糖果)的结果如下:
n u m s : [ 1 , 1 , 1 , 0 , 0 , 0 , 1 ] nums: [1, 1, 1, 0, 0, 0, 1] nums:[1,1,1,0,0,0,1],虽然 3 的位置也处于一个递增的位置上,但是右边还有数字比他大,所以无伤大雅。
第二次 for 循环,我们处理完之后,nums 变成了:
n
u
m
s
:
[
1
,
0
,
0
,
0
,
0
,
0
,
1
]
nums: [1, 0, 0, 0, 0, 0, 1]
nums:[1,0,0,0,0,0,1]。
最后我们以所有分到一颗糖的小朋友为中心,向周围扩展,看看周围的小朋友最少分到多少颗糖果(在不违反规则的情况下)。
代码
class Solution {
public:
int candy(vector<int>& ratings) {
int N = ratings.size();
vector<int> nums(N);
int f = false;
for (int i = 1; i < N; i++)
{
if (ratings[i] != ratings[i - 1])
{
f = true;
break;
}
}
if (!f)
return N;
f = 1;
for (int i = N - 1; i >= 0; i--)
{
nums[i] = f;
if (i != 0 && ratings[i] < ratings[i - 1])
f = 0;
if (i != 0 && ratings[i] > ratings[i - 1])
f = 1;
}
for (int i = 0; i < N; i++)
cout << nums[i] << ' ';
cout << '\n';
f = 1;
for (int i = 0; i < N; i++)
{
nums[i] *= f;
if (i != N - 1 && ratings[i] < ratings[i + 1])
f = 0;
if (i != N - 1 && ratings[i] > ratings[i + 1])
f = 1;
}
for (int i = 0; i < N; i++)
cout << nums[i] << ' ';
cout << '\n';
for (int i = 0; i < N; i++)
{
if (nums[i] == 1)
{
nums[i] = 1;
int j = i - 1;
while (j >= 0 && ratings[j] >= ratings[j + 1])
{
if (ratings[j] == ratings[j + 1])
nums[j] = max(nums[j], 1);
else
nums[j] = max(nums[j], nums[j + 1] + 1);
j--;
}
j = i + 1;
while (j < N && ratings[j] >= ratings[j - 1])
{
if (ratings[j] == ratings[j - 1])
nums[j] = max(nums[j], 1);
else
nums[j] = max(nums[j], nums[j - 1] + 1);
j++;
}
}
}
int ans = 0;
for (int i = 0; i < N; i++)
ans += nums[i];
return ans;
}
};
结果

作者能力有限,如果有任何错误之处,还请各位指教。(~ ̄▽ ̄)~
310

被折叠的 条评论
为什么被折叠?



