一群孩子做游戏,现在请你根据游戏得分来发糖果,要求如下:
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; } }
public static int candy(int[] arr) { // write code here int[] temp = new int[arr.length]; Arrays.fill(temp, 1); for (int t = 0; t < arr.length; t++) { if ((t + 1) <= arr.length - 1 && arr[t + 1] > arr[t]) getCandy(arr, temp, t + 1); } for (int t = arr.length - 1; t >= 0; t--) { if ((t - 1) >= 0 && arr[t - 1] > arr[t]) getCandy2(arr, temp, t - 1); } for (int i = 0, j = i + 1, k = i + 2; k < temp.length; i++, j++, k++) { if (temp[j] - temp[i] > 1 && temp[j] - temp[k] > 1) { if (temp[i] > temp[k]) { temp[j] = temp[i] + 1; } else { temp[j] = temp[k] + 1; } } } int ret = 0; for (int num : temp) { ret += num; } System.out.println(Arrays.toString(temp)); return ret; } private static void getCandy(int[] arr, int[] temp, int t) { temp[t]++; if ((t + 1) <= arr.length - 1 && arr[t + 1] > arr[t]) getCandy(arr, temp, t + 1); } private static void getCandy2(int[] arr, int[] temp, int t) { temp[t]++; if ((t - 1) >= 0 && arr[t - 1] > arr[t]) getCandy2(arr, temp, t - 1); }
class Solution: def candy(self , arr: List[int]) -> int: # write code here nums = [1 for i in range(len(arr))] for i in range(1, len(arr)): if arr[i] > arr[i - 1]: nums[i] = nums[i - 1] + 1 for j in range(len(arr)-1,0,-1): if arr[j] < arr[j - 1] and nums[j] >= nums[j - 1]: nums[j - 1] = nums[j] + 1 return sum(nums)