[LeetCode OJ] Candy 解题报告

题目地址:https://oj.leetcode.com/problems/candy/

题意:有一羣小孩排成一列,给他们发糖,保证每个人至少一个糖而且每个小孩得到的糖一定比 “与他相邻的且身高低于他”(如果有的话)的小孩得到的糖多,求最少发多少糖。

trick:两个相邻的小孩如果身高相等的话就忽略掉这两个小孩之间的比较。连续身高相等的小孩,除了处于波峯或者波谷的,都只发一颗糖是最优解的子集。

思路:这道题想了好几种方法都WA了,最后参考了网上的答案,发现这道题我以前做过。。。

   波谷的小孩只发一颗糖也是最优解的子集,正序和倒序各扫一般(有方向),遇到波谷就给这个小孩发一个糖,在波谷到波峯路径上的小孩得到的糖递增一个。

   最后,这里的处于波峯的小孩由于要满足左右两边的条件限制,所以得到的糖应该是左扫描和右扫描中的最大值。

技巧:先将数组头尾个插入一个身高接近无限大的小孩,这样原来的第一个小孩和最后一个小孩就不用特殊判断了。

#include <vector>
#include<iostream>
#define INF 0x7fffffff
using namespace std;
class Solution {
public:
    int candy(vector<int> &ratings) {
        ratings.insert(ratings.begin(),INF);
        ratings.push_back(INF);
        int size = ratings.size();
        if(size == 1) return 1;
        vector<int> tmp (size,1);//记录发糖数,初始化全为1
        for(int i=1; i<size-1; ++i){
            int j =size-1-i;
            int now1=ratings[i],now2=ratings[j];
            //正序扫一遍
            if(ratings[i-1]<now1 && now1<=ratings[i+1]){
                tmp[i] = tmp[i-1]+1;
            }
            else if(ratings[i-1]<now1 && now1>ratings[i+1]){
                tmp[i] = max(tmp[i-1]+1,tmp[i]);
            }
            //倒序扫一遍
            if(ratings[j+1]<now2 && now2<=ratings[j-1]){
                tmp[j] = tmp[j+1]+1;
            }
            else if(ratings[j+1]<now2 && now2>ratings[j-1]){
                tmp[j] = max(tmp[j+1]+1,tmp[j]);
            }
        }
        int ans=0;
        for(int i=1; i<size-1; ++i){
            ans+=tmp[i];
        }
        //cout<<ans<<endl;
        return ans;
    }
};

点赞