135 Candy
题目
题解
题目的要求:N个孩子站成一行,其中每个孩子有一个评分。要求:每个孩子至少要得到一颗糖;评分比相邻孩子高的,得到的糖也要比相邻的孩子多。求满足上述要求的最小发糖数。
因为第一个要求容易满足,所以先满足它,给每个孩子发一颗糖就行了。
对于第二个要求,为了尽量少发糖,可以采取弥补性发糖的策略,即只在不满足要求的情况下发糖。为了最低限度地进行弥补,可以采取如下贪心策略:按照评分从低到高的顺序,逐一对评分高于相邻孩子的孩子进行弥补。这样进行的弥补,都是在最小评分差距的情况下进行的,因此不会发出多余的糖果。
因为检查要求二和弥补操作都需要位置信息,所以要按照评分从低到高的顺序对数组的下标序列进行排序,用排序后的下标序列进行计算。
代码
class Solution {
public:
template <typename T>
vector<size_t> sort_indexes(const vector<T> &v) {
// initialize original index locations
vector<size_t> idx(v.size());
iota(idx.begin(), idx.end(), 0);
// sort indexes based on comparing values in v
sort(idx.begin(), idx.end(),
[&v](size_t i1, size_t i2) {return v[i1] < v[i2]; });
return idx;
}
int candy(vector<int>& ratings) {
vector<size_t> sorted_index = sort_indexes<int>(ratings);
vector<int> gives = vector<int>(ratings.size(), 1);
for (size_t i = 0; i < sorted_index.size(); i++)
{
int index = sorted_index[i];
int rate = ratings[index];
if (index == 0) {
if (rate > ratings[index + 1]) {
gives[index] = gives[index + 1] + 1;
}
}
if (index == ratings.size() - 1) {
if (rate > ratings[index - 1]) {
gives[index] = gives[index - 1] + 1;
}
}
if (index > 0 && index < ratings.size() - 1) {
bool gt_left = rate > ratings[index - 1];
bool gt_right = rate > ratings[index + 1];
if (gt_left && !gt_right) {
gives[index] = gives[index - 1] + 1;
}
if (!gt_left && gt_right) {
gives[index] = gives[index + 1] + 1;
}
if (gt_left && gt_right) {
gives[index] = max(gives[index - 1], gives[index + 1]) + 1;
}
}
}
return accumulate(gives.begin(), gives.end(), 0);
}
};