首先,LeetCode上有一道分糖果的题目:
https://leetcode.com/problems/candy/
在网上参考了一个很简单的题解思路,
将第一个数的糖果初始化为1,从第二个开始,正向遍历,如果当前数字比前一个大,当前的数的糖果加1。
接着反过来从倒数第二个开始,反向遍历,如果当前数字比后一个大,当前的糖果数为max(当前糖果数,后一个糖果数+1)
class Solution {
public:
int candy(vector<int>& ratings) {
int sum=0;
int n= ratings.size();
vector<int>arr(n,1);
for (int i=1;i<n;i++)
{
if (ratings[i]>ratings[i-1])arr[i] = arr[i-1]+1;
}
for (int i=n-2;i>=0;i--)
{
if (ratings[i]>ratings[i+1])arr[i] = max(arr[i],arr[i+1]+1);
}
for (int i=0;i<n;i++)sum+=arr[i];
return sum;
}
};
注意,此题中,最后一个数的邻域只有其前一个数,不包括第一个数;同理,第一个数的邻域只有第二个数,不包括最后一个数。如果将题目改为,“圆方桌”,将首位相互为邻域,解法为:, 注意是**‘’至少’的个数**
参考:
https://www.nowcoder.com/discuss/164189?type=0&order=0&pos=10&page=0
递归,注意当前递归终止的条件,如果当前数小于等于其左右两边的数,那么当前数的糖果数为1,并返回。
注意转换函数的使用,当数<0 或者数>=num时。每次递归之前也要对当前数进行转换。
#include<iostream>
#include<vector>
#include<algorithm>
#include<string.h>
using namespace std;
// int my_max = 0x7fffffff;
#define my_max 101000
int score[my_max] ;
int arr[my_max] ;
int num;
int transfor(int i)
{
int index=i;
if(i<0)
{
index = i+num;
}
else if (i>=num)
{
index = i-num;
}
return index;
}
int fun(int i) // dg!!!
{
i = transfor(i); // !!!
if(score[i]>0)return score[i];
int left = arr[transfor(i-1)];
int right = arr[transfor(i+1)];
int tmp = arr[i];
if (tmp<=left && tmp<=right) // !!!
{
return score[i] = 1;
}
else if (tmp>left && tmp>right)
{
return score[i] = max(fun(i-1),fun(i+1)) +1;
}
else if (tmp>left)
{
return score[i] = fun(i-1) +1;
}
else if (tmp>right)
{
return score[i] = fun(i+1)+ 1;
}
return 0;
}
int main()
{
int N;
scanf("%d",&N);
while(N--)
{
//int num;
int res = 0;
scanf("%d",&num);
for (int i=0;i<num;i++)
{
scanf("%d",&arr[i]);
}
for (int i=0;i<num;i++)score[i] = -1;
for (int i=0;i<num;i++)
{
if (score[i]<0)
{
fun(i);
}
}
for (int i=0;i<num;i++)
{
cout<<"i: "<<i<<" "<<"s: "<<score[i]<<endl;
res += score[i];
}
printf("%d\n",res);
}
getchar();
getchar();
return 0;
}