一群孩子做游戏,现在请你根据游戏得分来发糖果,要求如下:
1. 每个孩子不管得分多少,起码分到一个糖果。
2. 任意两个相邻的孩子之间,得分较多的孩子必须拿多一些糖果。(若相同则无此限制)
给定一个数组
代表得分数组,请返回最少需要多少糖果。
要求: 时间复杂度为
空间复杂度为
数据范围:
,
[1,1,2]
4
最优分配方案为1,1,2
[1,1,1]
3
最优分配方案是1,1,1
class Solution: def candy(self , arr ): # write code here res = [1] * len(arr) for i in range(1, len(arr)): if arr[i] > arr[i-1]: res[i] = res[i-1] + 1 for i in range(len(arr)-2, -1, -1): if arr[i] > arr[i+1]: res[i] = max(res[i+1] + 1, res[i]) return sum(res)
贪心算法
每次记录一个up连续上升的个数,down连续下降的个数,peak当前峰的高度。遍历一次。
O(n) time, O(1) space
int candy(vector& arr) {
int up = 0, down = 0, peak = 1, res = 1;
for (int i = 1; i < arr.size(); i++) {
res++;
if (arr[i] > arr[i - 1]) {
up++;
res += up;
down = 0;
peak = up + 1;
}
else if (arr[i] == arr[i - 1]) {
up = 0;
down = 0;
peak = 1;
}
else {
up = 0;
res += down;
down++;
if (down >= peak) res++;
}
}
return res;
}
public int candy (int[] arr) {
int n=arr.length;
int[]dp=new int[n];//记录每个孩子的糖果数目
//从左向右,若是右边得分高,那么就得到左边的糖果数+1,否则设为1
dp[0]=1;
for(int i=1;i<n;i++){
if(arr[i]>arr[i-1]) dp[i]=dp[i-1]+1;
else dp[i]=1;
}
//从右向左遍历,若是左边比右边得分高,那么糖果数右边+1
int sum=dp[n-1];
for(int i=n-2;i>=0;i--){
if(arr[i]>arr[i+1]&&(dp[i]<=dp[i+1])){
dp[i]=dp[i+1]+1;
}
sum+=dp[i];
}
return sum;
} public int candy (int[] arr) {
// write code here
int a[]=new int[arr.length];
a[0]=1;
int sum=0;
if(arr.length==1){
sum=1 ;
}else{
for(int i=0;i<arr.length-1;i++){
if(arr[i+1]>arr[i]){
a[i+1]=a[i]+1;
}else {
a[i+1]=1;
}
}
}
for(int i=0;i<a.length-1;i++){
if(arr[i+1]<arr[i]&&a[i+1]==a[i]){
a[i]=a[i]+1;
if(i>=1){i=i-2;}
else {i=0;}
}
}
for(int i=0;i<a.length;i++){
sum+=a[i];
}
return sum;
} class Solution { public: /** * pick candy * @param arr int整型vector the array * @return int整型 */ int candy(vector<int>& arr) { if(arr.size() < 2){ return arr.size(); } vector<int> res(arr.size(), 1); //向右遍历 for(int i = 1; i < arr.size(); i++){ if(arr[i] > arr[i-1]){ res[i] = res[i-1] + 1; } } for(int i = arr.size() - 1; i > 0; i--){ //向左遍历 if(arr[i] < arr[i-1]){ res[i-1] = max(res[i-1], res[i]+1); } } int _count = 0; for(int i = 0; i < res.size(); i++){ _count = res[i] + _count; } return _count; } };//把所有孩子的糖果数初始化为 1; 先从左往右遍历一遍,//如果右边孩子的评分比左边的高,则//右边孩子的糖果数更新为左边孩子的 糖果数加 1;//再从右往左遍历一遍,如果左边孩子的评分//比右边的高,且左边孩子当前的糖果数//不大于右边孩子的糖果数,则左边孩子的糖果数更新为//右边孩子的糖果数加 1。通过这两次遍历, 分配的糖果就可以满足题目要求了。
/**
* pick candy
* @param arr int整型一维数组 the array
* @return int整型
*/
function candy( arr ) {
// write code here
let res = arr.length
let list = arr.map(item => 1)
for(let i = 1; i < arr.length; i++){
if(arr[i] > arr[i - 1]){
res += list[i - 1]
list[i] += list[i - 1]
}
}
for(let i = arr.length - 1; i > 0; i--){
if(arr[i - 1] > arr[i]){
let add = list[i - 1] > list[i] ? 0 : list[i] - list[i - 1] + 1
res += add
list[i - 1] += add
}
}
return res
}
module.exports = {
candy : candy
};
class Solution {
public:
/**
* pick candy
* @param arr int整型vector the array
* @return int整型
*/
int candy(vector<int>& arr) {
// 时间复杂度O(N),空间复杂度O(N)
vector<int> tmp(arr.size(), 1);
for (int i = 1; i < arr.size(); ++i) {
if (arr[i] > arr[i - 1]) tmp[i] = tmp[i - 1] + 1;
}
for (int i = arr.size() - 2; i >= 0; --i) {
if (arr[i] > arr[i + 1] && tmp[i] <= tmp[i + 1]) tmp[i] = tmp[i + 1] + 1;
}
int res = 0;
for (int i = 0; i < tmp.size(); ++i) res += tmp[i];
return res;
}
}; 相邻可有两个方向,同时根据依赖方向来决定遍历顺序
class Solution {
public:
/**
* pick candy
* @param arr int整型vector the array
* @return int整型
*/
int candy(vector<int>& arr) {
// write code here
// base case
if(arr.size() <= 1) return arr.size();
// 初始 每个人一颗
vector<int> nums(arr.size(), 1);
//比左边 1->4->2->7->9 依赖的是左边 需从左往右遍历
for (int i = 1; i < arr.size(); i++) {
// 该方向相邻且得分较多但糖果不多
if(arr[i - 1] < arr[i] && nums[i - 1] >= nums[i]){
nums[i] = nums[i - 1] + 1;
}
}
// 比右边 1<-4<-2<-7<-9 从右往左遍历 依赖的是右边
for(int i = arr.size() - 2; i >= 0; i--){
if(arr[i + 1] < arr[i] && nums[i + 1] >= nums[i]){
nums[i] = nums[i + 1] + 1;
}
}
int total = 0;
for(int i = 0; i < nums.size(); i++){
total += nums[i];
}
return total;
}
}; import java.util.*;
public class Solution {
/**
* pick candy
* @param arr int整型一维数组 the array
* @return int整型
*/
public int candy (int[] arr) {
// write code here
int[] left=new int[arr.length];
int[] right=new int[arr.length];
int candy=0;
left[0]=1;
right[arr.length-1]=1;
for(int i=1;i<=arr.length-1;i++){
if(arr[i]>arr[i-1]){
left[i]=left[i-1]+1;
}else{
left[i]=1;
}
}
for(int i=arr.length-2;i>=0;i--){
if(arr[i]>arr[i+1]){
right[i]=right[i+1]+1;
}else{
right[i]=1;
}
}
for(int i=0;i<=arr.length-1;i++){
candy=candy+Math.max(left[i],right[i]);
}
return candy;
}
} class Solution {
public:
/**
* pick candy
* @param arr int整型vector the array
* @return int整型
*/
int candy(vector<int>& arr) {
// write code here
const int n = arr.size();
vector<int> increment(n);
for(int i = 1,inc = 1; i < arr.size(); i++){
if(arr[i] > arr[i - 1]) increment[i] = max(inc++,increment[i]);
else inc = 1;
}
for(int i = arr.size() - 2,inc = 1; i >= 0; i--){
if(arr[i] > arr[i + 1]) increment[i] = max(inc++,increment[i]);
else inc = 1;
}
int sum = 0;
for(int i = 0; i < increment.size(); i++){
sum += increment[i];
}
sum += n;
return sum;
}
}; using System;
using System.Collections.Generic;
class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* pick candy
* @param arr int整型一维数组 the array
* @return int整型
*/
public int candy (List<int> arr) {
int cur = 0;
int curc = 1;
int pre = 1;
int res = 1;
for(int i = 1; i < arr.Count; i++){
if(arr[i] > arr[i-1]){
res += pre + 1;
pre++;
cur = i;
curc = pre;
}
else if(arr[i] == arr[i - 1]){
cur = i;
res++;
pre = 1;
curc = pre;
}
else{
res += i - cur;
if(i - cur >= curc) res++;
pre = 1;
}
//Console.WriteLine(res);
}
return res;
}
} /**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* pick candy
* @param arr int整型一维数组 the array
* @return int整型
*/
function candy( arr ) {
// write code here
let res=arr.map(v=>1)
for(let i=1;i<arr.length;i++){ //从一开始比较
if(arr[i]>arr[i-1]){
res[i]=res[i-1]+1
}
}
for(let i=arr.length-2;i>=0;i--){
if(arr[i]>arr[i+1]){
if(res[i]>res[i+1])continue
res[i]=Math.max(res[i],res[i+1])+1
}
}
return res.reduce((p,c)=>p+c,0)
}
module.exports = {
candy : candy
}; import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* pick candy
* @param arr int整型一维数组 the array
* @return int整型
*/
public int candy (int[] arr) {
// write code here
int n = arr.length;
int[] count = new int[n];
Arrays.fill(count, 1);
for(int i = 1; i < n; i++) {
if(arr[i] > arr[i - 1]) count[i] = count[i - 1] + 1;
}
for(int i = n - 2; i >= 0; i--) {
if(arr[i] > arr[i + 1]) count[i] = Math.max(count[i + 1] + 1, count[i]);
}
int res = 0;
for(int i = 0; i < n; i++) {
res += count[i];
}
return res;
}
} public class Solution {
/**
* 给定一个数组 arrarr 代表得分数组,请返回最少需要多少糖果。
*
* pick candy
* @param arr int整型一维数组 the array
* @return int整型
*/
public int candy (int[] arr) {
int candy[] = new int[arr.length];
for (int i = 0; i < candy.length; i++) {
candy[i] = 1;
}
for (int i = 1; i < arr.length; i++) {
if (arr[i] > arr[i - 1]) {
candy[i] = candy[i - 1] + 1;
}
}
int count = 0 ;
for (int i = arr.length - 1; i > 0; i--) {
if (arr[i - 1] > arr[i] && candy[i - 1] <= candy[i]) {
candy[i - 1] = candy[i] + 1;
}
count += candy[i];
}
return count += candy[0];
}
} import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* pick candy
* @param arr int整型一维数组 the array
* @return int整型
*/
// 参考代码随想录
public int candy (int[] arr) {
// write code here
int len = arr.length;
int res = 0;
int[] preMin = new int[len];
int[] sufMin = new int[len];
Arrays.fill(preMin, 1);
Arrays.fill(sufMin, 1);
for (int i = 1; i < len; i++) if (arr[i] > arr[i - 1]) preMin[i] = preMin[i-1] + 1;
for (int i = len - 2; i >= 0; i--) if (arr[i] > arr[i + 1]) sufMin[i] = sufMin[i+1] + 1;
for (int i = 0; i < len; i++) res += Math.max(preMin[i], sufMin[i]);
return res;
}
}