Idiot-maker

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

https://leetcode.com/problems/candy/

There are N children standing in a line. Each child is assigned a rating value.

You are giving candies to these children subjected to the following requirements:

  • Each child must have at least one candy.
  • Children with a higher rating get more candies than their neighbors.

What is the minimum candies you must give?

解题思路:

开始没看清题意,以为相邻的相同rating,获得candy数量也必须一样。实际上这点没要求。

所以用了下面的方法,从左到右和从右到左分别找出连续最大长度的递增子数列,再将这两者比较,这样就可以确定那个拿到最多candy的顶点了。然后从这个顶点分别向左右扩展,遇到大的+1,相等的不变,小的-1,直到遇到数组两头。但因为题意理解错误,也就无法验证正确性了。

public class Solution {
    public int candy(int[] ratings) {
        if(ratings.length == 0){
            return 0;
        }
        if(ratings.length == 1){
            return 1;
        }
        int longestPeakIndexUp = 0, longestPeakIndexDown = 0;
        int longestLengthUp = 1, maxLengthUp = 1, longestLengthDown = 1, maxLengthDown = 1;
        for(int i = 1; i < ratings.length; i++){
            if(ratings[i] > ratings[i - 1]){
                longestLengthUp++;
                if(i == ratings.length - 1){
                    if(longestLengthUp > maxLengthUp){
                        maxLengthUp = longestLengthUp;
                        longestPeakIndexUp = i;
                    }
                }
            }else{
                if(longestLengthUp > maxLengthUp){
                    maxLengthUp = longestLengthUp;
                    longestPeakIndexUp = i - 1;
                }
                longestLengthUp = 1;
            }
        }
        
        for(int i = ratings.length - 2; i >= 0; i--){
            if(ratings[i] > ratings[i + 1]){
                longestLengthDown++;
                if(i == 0){
                    if(longestLengthDown > maxLengthDown){
                        maxLengthDown = longestLengthDown;
                        longestPeakIndexDown = i;
                    }
                }
            }else{
                if(longestLengthDown > maxLengthDown){
                    maxLengthDown = longestLengthDown;
                    longestPeakIndexDown = i + 1;
                }
                longestLengthDown = 1;
            }
        }
        
        int maxLength = maxLengthUp;
        int longestPeakIndex = longestPeakIndexUp;
        if(maxLengthUp < maxLengthDown){
            maxLength = maxLengthDown;
            longestPeakIndex = longestPeakIndexDown;
        }
        
        int candyNumbers = maxLength, thisNumber = maxLength;
        for(int i = longestPeakIndex + 1; i < ratings.length; i++){
            if(ratings[i] > ratings[i - 1]){
                thisNumber++;
            }else if(ratings[i] < ratings[i - 1]){
                thisNumber--;
            }
            candyNumbers += thisNumber;
        }
        thisNumber = maxLength;
        for(int i = longestPeakIndex - 1; i >= 0; i--){
            if(ratings[i] > ratings[i + 1]){
                thisNumber++;
            }else if(ratings[i] < ratings[i + 1]){
                thisNumber--;
            }
            candyNumbers += thisNumber;
        }
        return candyNumbers;
    }
}

发现了错误后,意味着有两个变化。第一,12333321这样的数列,中间的3完全可以全是1。第二,42341这样的数列,num就是21231。注意倒数第二个数字4,它的num来自于左侧较长的递增数列。

理解了题意,代码倒是简单了。首先将默认的num都置为1。然后从左到右递增就+1,不变就置为1。从右到左递增+1,但是如果前面已经赋值了,而且此时的值不如以前大,比如上面的4位置,就不能更新值,否则会打破从左到右的递增。这样的值基本上是左右都是递增的peak。

public class Solution {
    public int candy(int[] ratings) {
        int[] num = new int[ratings.length];
        if(ratings.length == 0 || ratings.length == 1){
            return ratings.length;
        }
        for(int i = 0; i < num.length; i++){
            num[i] = 1;
        }
        //从左到右更新
        for(int i = 1; i < ratings.length; i++){
            if(ratings[i] > ratings[i - 1]){
                num[i] = num[i - 1] + 1;
            }else if(ratings[i] == ratings[i - 1]){
                num[i] = 1;
            }
        }
        //从右到左更新
        for(int i = ratings.length - 2; i >= 0; i--){
            if(ratings[i] > ratings[i + 1]){
                int temp = num[i + 1] + 1;
                if(temp >= num[i]){
                    num[i] = temp;
                }
            }
        }
        int total = 0;
        for(int i = 0; i < num.length; i++){
            total += num[i];
        }
        return total;
    }
}

 

posted on 2015-03-20 20:03  NickyYe  阅读(247)  评论(0编辑  收藏  举报