No.135 Candy

No.135 Candy

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?

 Tags: Greedy

 

分析:分糖果问题:

每个小朋友分到的糖果数与且与他左右的两个小朋友有关【与trapping rain water相类似,但不是考虑所有所有两侧的】
当i小朋友比他旁边的rating高时,i就要比rating小的至少多一个糖果;若它比左右两侧都大,可以置为1
问题解决步骤:[辅助数组num]
1.从左往右扫描,若当前i的rating大于左侧的,i的糖果数为左侧的糖果数+1,否则,置为1
2.从右往左扫描,若当前i的rating大于右侧的,i的糖果数右侧的糖果数+1,否则,置为1
3.当前i的最小糖果数为两次扫描结果中最大的那个
4.累加所有i的糖果数
【2、3、4在同一次循环中进行】

 

 

第一个提交【错】:题意理解有问题:是相邻的,rate高的比低的糖果要多;而不是对于整个数组而言。

 1 class Solution
 2 {
 3 public:
 4     int candy(vector<int> &ratings)
 5     {
 6         int size = ratings.size();
 7         if(size == 0)
 8             return 0;
 9         if(size == 1)
10             return 1;
11         //不知道是否允许改变原数组
12         sort(ratings.begin(),ratings.end());
13         
14         int res=0;
15         int index = 0;
16         int tmp;
17         int sameCount=1;//此时相同优先级的个数
18         int currentCount = 1;//当前类优先级得到的candy个数
19         while(index < size)
20         {
21             sameCount=1;
22             tmp=ratings[index];
23             while(index<size-1 && ratings[index+1] == tmp)//必须要保证index+1不越界!!
24             {
25                 index++;
26                 sameCount++;
27             }
28             res += sameCount*currentCount;
29             currentCount++;
30             index++;//勿忘!!!
31         }
32         return res;
33     }
34 };
View Code

 

最终版:

 1 #include "stdafx.h"
 2 #include <vector>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 class Solution
 8 {
 9 public:
10     int candy(vector<int> &ratings)
11     {
12       /*
13         分糖果问题:
14         每个小朋友分到的糖果数与且与他左右的两个小朋友有关【与trapping rain water相类似,但不是考虑所有所有两侧的】
15         当i小朋友比他旁边的rating高时,i就要比rating小的至少多一个糖果;若它比左右两侧都大,可以置为1
16         问题解决步骤:[辅助数组num]
17             1.从左往右扫描,若当前i的rating大于左侧的,i的糖果数为左侧的糖果数+1,否则,置为1
18             2.从右往左扫描,若当前i的rating大于右侧的,i的糖果数右侧的糖果数+1,否则,置为1
19             3.当前i的最小糖果数为两次扫描结果中最大的那个
20             4.累加所有i的糖果数
21             【2、3、4在同一次循环中进行】
22       */
23 
24         int size = ratings.size();
25         if(size == 0)
26             return 0;
27         if(size == 1)
28             return 1;
29 
30         int *num = new int[size];
31         for(int i=0; i<size; i++)
32         {//从左往右扫描
33             if(i>0 && ratings[i]>ratings[i-1])//注意i的范围,保证左侧不越界!!!
34                 num[i] = num[i-1]+1;
35             else
36                 num[i] = 1;
37         }
38         int res=0;
39         int cur=0;//记录对i来说,只考虑它右边的rating,所分的糖果数
40         for(int i=size-1; i>=0; i--)
41         {//从右往左扫描
42             cur = 1;
43             if(i<size-1 &&ratings[i]>ratings[i+1])
44                 cur = num[i+1]+1;
45             res += (num[i]>cur? num[i] : cur);
46             num[i] = cur;//需要保存当前的cur,以供i-1使用!!!
47         }
48         
49         delete[] num;
50         return res;
51     }
52 };
53 
54 int main()
55 {
56     Solution sol;
57 //    int data[] = {1,2,5,5,10};//1+2+3+1+2=9
58 //    int data[] = {1,2,3,5,7};//1+2+3+4+5=15
59     int data[] = {1,1,1,1,1};//5
60     vector<int> test(data, data+sizeof(data)/sizeof(int));
61     cout << sol.candy(test);
62     return 0;
63 }

 

  

 

 

posted @ 2015-05-27 11:59  人生不酱油  阅读(285)  评论(0编辑  收藏  举报