分发糖果
n
个孩子站成一排。给你一个整数数组 ratings
表示每个孩子的评分。
你需要按照以下要求,给这些孩子分发糖果:
- 每个孩子至少分配到
1
个糖果。 - 相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
示例 1:
输入:ratings = [1,0,2] 输出:5 解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。
示例 2:
输入:ratings = [1,2,2] 输出:4 解释:你可以分别给第一个、第二个、第三个孩子分发 1、2、1 颗糖果。 第三个孩子只得到 1 颗糖果,这满足题面中的两个条件。
提示:
n == ratings.length
1 <= n <= 2 * 104
0 <= ratings[i] <= 2 * 104
思路:
- 每个孩子至少分配到
1
个糖果。 - 相邻两个孩子评分更高的孩子会获得更多的糖果。
对于①规则,我们先把所有的孩子附值为1,就是每个小孩糖果数量为1。
对于②规则,我们需要让小孩ratings值大的比隔壁小的糖果数量多一些,所以我们可以先从左遍历到右,如果右边的ratings比较大,则+1 ,保存在leftt数组中;
之后,同理我们从右遍历到左,如果左边的ratings更大,则 + 1,保存在right数组中,之后我们对于每一个小孩,取出max(left[i] , right[i]),就可以同时遵守好两条规则了。
代码如下:
class Solution {
public int candy(int[] ratings) {
int left[] = new int[ratings.length];
int right[] = new int[ratings.length];
for(int i = 0;i < ratings.length; i++) {
left[i] = 1;
right[ratings.length - 1 - i] = 1;
if(i != 0 && ratings[i] > ratings[i-1]) {
left[i] = left[i-1] + 1;
}
int n = ratings.length - 1 - i;
if(n != ratings.length-1 && ratings[n] > ratings[n+1]) {
right[n] = right[n+1] + 1;
}
}
int ans = 0;
for(int i = 0;i < ratings.length; i++) {
ans += Math.max(left[i],right[i]);
}
return ans;
}
}
接雨水
给定 n
个非负整数表示每个宽度为 1
的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例 2:
输入:height = [4,2,0,3,2,5] 输出:9
提示:
n == height.length
1 <= n <= 2 * 104
0 <= height[i] <= 105
思路:使用双指针法,向中间聚拢的同时,维护左边最大值和右边最大值,如果出现height[left] > height[right]的情况,说明左边最大值maxLeft 肯定 > height[right],我们就可以让答案加上(right Max- height(max))也就是可以接到雨水的部分。
class Solution {
public int trap(int[] height) {
int left = 0;
int right = height.length - 1;
int leftMax = height[left];
int rightMax = height[right];
int ans = 0;
while(left < right){
leftMax = Math.max(height[left],leftMax);
rightMax = Math.max(height[right],rightMax);
if(height[left] > height[right]){
ans += (rightMax - height[right]);
right--;
}else{
ans += (leftMax - height[left]);
left++;
}
}
return ans;
}
}