分发糖果
解题思路:贪心算法、两次遍历
class Solution { public int candy(int[] ratings) { int len = ratings.length; if(len==0){ return 0; } int[] cands = new int[len]; for(int i=0;i<len;i++){ cands[i] = 1; } for(int i=0;i<len-1;i++){ if(ratings[i+1]>ratings[i]&&cands[i+1]<=cands[i]){ cands[i+1]=cands[i]+1; } } for(int i=len-1;i>0;i--){ if(ratings[i-1]>ratings[i]&&cands[i-1]<=cands[i]){ cands[i-1]=cands[i]+1; } } int sum = 0; for(int i=0;i<len;i++){ sum += cands[i]; } return sum; } }
第二种方法:
解题思路:把所有的情形的分界点分成三类,至于为什么这样子分类,是根据该题的具体情形考虑才这样子分类的。
(下--上)作为分界点
(下--平)作为分界点
(上--平)作为分界点
以上面三种分界点分成很多部分来分别计算每一部分的糖果数。
class Solution { public int candy(int[] ratings) { int len = ratings.length; if(len<=1){ return len; } int up=0; int down=0; int old_scope = 0; int new_scope = 0; int candys = 0; for(int i=1;i<len;i++){ new_scope = ratings[i]>ratings[i-1]?1:(ratings[i]<ratings[i-1]?-1:0); if(old_scope<0&&new_scope>=0||old_scope>0&&new_scope==0){ candys+=up*(1+up)/2+down*(1+down)/2+Math.max(up,down); up=0; down=0; } if(new_scope==1){ up++; } if(new_scope==-1){ down++; } if(new_scope==0){ candys++; } old_scope = new_scope; } candys+=up*(1+up)/2+down*(1+down)/2+Math.max(up,down)+1; return candys; } }