135. Candy
一、题目
1、审题
2、分析
每个小孩对应一个等级,每个小孩至少分一颗糖,紧挨着的等级高的小孩要比紧挨着的等级低的小孩的糖果多,求至少要分几颗糖果。
二、解答
1、思路:
方法一、
考虑到每个小孩的分到的糖果数受左右两边的小孩等级的影响。故:
①、找出所有小孩中等级最低的小孩1,分一棵糖,且他左边若有小孩2且等级高于小孩1,则赋小孩2糖果为 小孩1糖果 + 1,最终小孩2 分的糖果要大于等于此数。
同理,小孩1 右边的同伴小孩3 若等级大于小孩1,也先分配 (小孩1)+1,小孩3最终分配的糖果要大于次数。
②、将小孩1左边的所有小孩按照 ① 继续递归,将小孩1右边的小孩按照①递归。
③、最终将所有小孩分配的糖果相加即可。
public int candy(int[] ratings) { int len = ratings.length; int[] cost = new int[len]; candyHelper(ratings, cost, 0, len - 1); int result = 0; for (int i = 0; i < len; i++) result += cost[i]; return result; } private void candyHelper(int[] ratings, int[] cost, int start, int end) { if(start > end) return; int minIndex = start; // rating 最小的下标 for (int j = start + 1; j <= end; j++) { if(ratings[minIndex] > ratings[j]) minIndex = j; } cost[minIndex] = Math.max(cost[minIndex], 1); if(minIndex -1 >= start && ratings[minIndex - 1] != ratings[minIndex]) // 与左边不相等 cost[minIndex - 1] = Math.max(cost[minIndex - 1], cost[minIndex] + 1); if(minIndex + 1 <= end && ratings[minIndex + 1] != ratings[minIndex]) // 与右边不相等 cost[minIndex + 1] = Math.max(cost[minIndex + 1], cost[minIndex] + 1); candyHelper(ratings, cost, start, minIndex - 1); candyHelper(ratings, cost, minIndex + 1, end); }
方法二、
①、新建一个 cost 数组,初值均为 1;
②、从前向后遍历 ratings ,若后一个元素的 rating 大于前一个,则 后一个元素的 cost 为 前一个的 cost 值 + 1
③、从后向前遍历 ratings,若前一个元素的 rating 大于后一个,则前一个元素的 cost 为 当前 cost 与 后一个cost值 + 1 的两者最大值。
public int candy2(int[] ratings) { int len = ratings.length; if(len < 2) return len; int[] cost = new int[len]; Arrays.fill(cost, 1); // Scan from left to right, to make sure right higher rated child gets 1 more candy than left lower rated child for (int i = 1; i < len; i++) { if(ratings[i] > ratings[i - 1]) cost[i] = cost[i - 1] + 1; } // Scan from right to left, to make sure left higher rated child gets 1 more candy than right lower rated child for (int i = len - 1; i > 0; i--) { if(ratings[i - 1] > ratings[i]) cost[i - 1] = Math.max(cost[i - 1], cost[i] + 1); } int result = 0; for (int i = 0; i < len; i++) result += cost[i]; return result; }