LeetCode | Candy
2014-01-02 10:49
232 查看
题目:
There are N children standing in a line. Each child is assigned a rating value.You are giving candies to these children subjected to the following requirements:
Each child must have at least one candy.
Children with a higher rating get more candies than their neighbors.
What is the minimum candies you must give?
思路:
思路1:首先要考虑,题目中没有提到连续两个小孩,当他们的ratings相同时应当如何处理。例如,144321。显然,两个ratings为4的小孩不会拿到相同的candy,并且两者之间没有关系。所以我们可以将ratings相同且相邻的小孩分成两个子队列来考虑。由于上述过程中, 我们将相等的情况排除了,所以在接下来的讨论中,我们可以知道两个相邻的小孩的情况只可能为大于或者小于的关系。
1) 最简单的情况是k个小孩,他们是连续递增或者递减的关系。则candy总数是(1+k)*k/2。
2)在1)的条件上增加复杂度,k个小孩,先递增再递减。这时候两段都是从个数为1开始发放candy,向中间递推直到遇到最大值。最大值这个位置应当取两段递推的较大值。
3)复杂的情况都能够划分为如上1)与2)的子队列。
因此,我们遍历一遍一个不包含相等ratings的队列来找到所有最小值,这些值都应当取1。接下来,我们取相邻最小值组成依次计算,如3)所述。每个部分按照1),2)的计算方法去发放candy。注,开始与结束的位置需要特殊考虑。
思路2:
首先,每个小孩发一个candy。
然后,从右往左,当ratings递减时依次累加发candy。
最后,从左往右,当ratings递增时依次累加发candy,遇到最高点时注意不要覆盖上一步的数据。
整个过程可以由如下的图示来表示:
代码:
思路1:class Solution { public: int count; vector<int> ratings; int candy(vector<int> &ratings) { this->ratings = ratings; count=0; int begin=0;int end=1; while(ratings.size()>end) { if(ratings[end-1]==ratings[end]) { countBottom(begin,end-1); begin=end; } end++; }; countBottom(begin,end-1); //将相邻位置rating相同的队列分割为子队列 return count; } void countBottom(int i, int j) { if(i==j) { count+=1; return; } else if(i+1==j) { count+=3; return; } //数目小于2的情况,一定单调 vector<int> bottom; for(int cur=i+1;cur<j;cur++) { if(cur == i+1&&ratings[cur-1]<ratings[cur]) { bottom.push_back(cur-1); } else if(cur == i+1&&ratings[cur-1]>ratings[cur]) { bottom.push_back(cur-2); } if(ratings[cur-1]>ratings[cur]&&ratings[cur]<ratings[cur+1]) { bottom.push_back(cur); } if(cur == j-1&&ratings[cur]>ratings[cur+1]) { bottom.push_back(cur+1); } else if(cur == j-1&&ratings[cur]<ratings[cur+1]) { bottom.push_back(cur+2); } } //寻找队列中的最小值,特殊考虑开始与结束位置 if(bottom.size()>0) { count+=bottom.size(); if(bottom[0]==i-1) { count--; } if(bottom[bottom.size()-1]==j+1) { count--; } //开始与结束为止可能是个无效的位置 for(int i=1;i<bottom.size();i++) { if(bottom[i-1]+1<=bottom[i]-1) { int max=ratings[bottom[i-1]+1]; int index=bottom[i-1]+1; for(int j=bottom[i-1]+1;j<bottom[i];j++) { if(ratings[j]>max) { max=ratings[j]; index=j; } } //找到最大值的位置 count+=((index-(bottom[i-1]+1))<((bottom[i]-1)-index)?(((bottom[i]-1)-index)+2):((index-(bottom[i-1]+1))+2)); //最大值的取值 if(index>(bottom[i-1]+1)) { count+=((index-(bottom[i-1]+1))*(index-(bottom[i-1]+1)+3)/2); } //最大值的左侧 if(index<(bottom[i]-1)) { count+=(((bottom[i]-1)-index)*((bottom[i]-1)-index+3)/2); } //最大值的右侧 } } } } };
思路2:
class Solution { public: int* candies; int candy(vector<int> &ratings) { candies = new int[ratings.size()]; for(int i = 0; i < ratings.size(); i++){ candies[i] = 1; } for(int i = ratings.size() - 1; i > 0; i--){ if(ratings[i] < ratings[i - 1]){ candies[i - 1] = candies[i] + 1; } } for(int i = 0; i < ratings.size() - 1; i++){ if(ratings[i] < ratings[i + 1]){ int tmp = candies[i] + 1; if(candies[i + 1] < tmp){ candies[i + 1] = tmp; } } } int sum = 0; for(int i = 0; i < ratings.size(); i++){ sum += candies[i]; } return sum; } };
相关文章推荐
- leetcode - Candy
- [LeetCode] Candy
- Candy:对样例存在困惑的一道leetcode
- [LeetCode] 130: Candy
- LeetCode - Candy
- 【leetcode】Candy
- 【leetcode】 Candy (hard,pick one)
- LeetCode:Candy
- LeetCode | Candy
- LeetCode Candy 两种解法
- LeetCode (Candy)
- Leetcode-candy
- leetcode: Candy
- leetcode-Candy
- [LeetCode] Candy
- leetcode -- Candy -- 重点
- LeetCode——Candy
- LeetCode 笔记25 Candy (艰难的调试)
- LeetCode-Candy
- LeetCode 135 Candy