135. 分发糖果
这道题最主要的就是要和左右两个孩子比较,但遍历到每个孩子时同时比较左右两边会顾此失彼,例如当自己提高后,左边比自己评分高的孩子要不要提高糖果数,再左边的呢,比较麻烦,写倒也可以写,不过我写了个发现不符合时间要求,对于这种要同时从两个维度考虑问题的题,我们可以先确定一个维度,再去确定另一个维度,我们可以先从左至右只比较左边孩子和当前孩子,再从右至只左比较当前孩子和右边孩子,这样时间复杂度降下来了,也比较容易理解。
class Solution {
public:
int candy(vector<int>& ratings) {
vector<int> sweets(ratings.size(), 1);
for (int i = 1; i < sweets.size(); i++) {
if (ratings[i] > ratings[i - 1])
sweets[i] = sweets[i - 1] + 1;
}
for (int i = sweets.size() - 2; i >= 0; i--) {
if (ratings[i] > ratings[i + 1])
sweets[i] = max(sweets[i + 1] + 1, sweets[i]);
}
int result = 0;
for (int i = 0; i < ratings.size(); i++) {
result += sweets[i];
}
return result;
}
};
406. 根据身高重建队列
这个题和上面的题类似,也是同时要从两个维度考虑问题,我们可以先考虑一个维度,如果先考虑k的话,对k排序也没什么意义,所以要先考虑h,对h排序,降序排列,然后在把排列后的队列中每个人按他的k作为序号插入到新队列中,为什么可以这样呢,因为此时每个人前面的一定都是比他高的人,那么他按k作为序号插入是一定满足他的k的要求的。
class Solution {
public:
static bool cmp(vector<int> &x, vector<int> &y) {
if (x[0] == y[0])
return x[1] < y[1];
else
return x[0] > y[0];
}
vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
sort(people.begin(), people.end(), cmp);
list<vector<int>> que;
for (auto &person : people) {
auto it = que.begin();
int position = person[1];
while (position--) {
it++;
}
que.insert(it, person);
}
vector<vector<int>> result(que.begin(), que.end());
return result;
}
};
这里用链表是因为用vector的话插入会引起扩容,消耗比较多的时间(关于vector的原理可看vector原理讲解)