LeetCode困难题(分发糖果--接雨水)

分发糖果

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:

LeetCode困难题(分发糖果--接雨水)_第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;
    }
}

你可能感兴趣的:(leetcode,算法)