zoukankan      html  css  js  c++  java
  • 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?

    Solution:

    最开始想到的是 从左往右循环,如果遇到 左边小于右边的, 右边的+1。 遇到左边大于右边的, 回退,直到右边大于左边,给每一个元素+1, 这样时间复杂度是O(n^2)。 得降:

    接着就想到用stack,循环从左边开始,如果发现左边比右边大 则入stack,直到左边比右边小 ,然后出stack,给每个出stack的数加上其在stack里面的位置,即深度。

    如果当前点比它前面的点大呢? candy[i] = candy[i - 1] + 1; 否则, candy[i] = 1;

    这里新建了一个数组,rating, 它扩展了原数组,末尾加了一个-1, 用于对最后一个元素进行判断。

    对于栈底元素,即临界元素,其值应该等于左边得到的值 和通过栈的到的值中间最大的那一个。

    还要在循环外, 对stack进行一次操作。

    对最后一个点 还得讨论,

    1)如果最后一个点 比 前一个小 则不变
    2)比前一个大 则为D(n -1) + 1
     
    464 ms过大测试~~时间复杂度 O(n)。
     1 public class Solution {
     2     public int candy(int[] ratings) {
     3         // Note: The Solution object is instantiated only once and is reused by each test case.
     4         int l = ratings.length;
     5         int[] rating = new int[l + 1];
     6         for(int i = 0; i < l; i ++){
     7             rating[i] = ratings[i];
     8         }
     9         rating[l] = -1;
    10         int sum = 0;
    11         int d = 0;
    12         int[] candy = new int[l];
    13         Stack<Integer> st = new Stack<Integer>();
    14         for(int i = 0; i < l; i ++){
    15             if(i > 0 && rating[i] > rating[i - 1]){
    16                 candy[i] = candy[i - 1] + 1;
    17             }else{
    18                 candy[i] = 1;
    19             }
    20             if(rating[i] > rating[i+1]){
    21                 st.push(i);
    22             }else{
    23                 d = st.size();
    24                 if(d > 0){
    25                     for(int ii = 0; ii < d - 1; ii ++){
    26                         int cur = st.pop();
    27                         candy[cur] += ii+1;
    28                     }
    29                     int cur = st.pop();
    30                     candy[cur] = ((d + 1) > candy[cur] ? (d + 1) : candy[cur]);// d+1 原因: 最小的那个元素没有入栈,栈的深度少了1.
    31                 }
    32             }
    33             
    34         }
    35         d = st.size();
    36         for(int ii = 0; ii < d - 1; ii ++){
    37             int cur = st.pop();
    38             candy[cur] += ii;
    39         }
    40         int cur = st.pop();
    41         candy[cur] = (d > candy[cur] ? d : candy[cur]);
    42         for(int i = 0; i < candy.length; i ++){
    43             sum += candy[i];
    44         }
    45         return sum;
    46     }
    47 }

     其实,这一题可以想象成一个波, 它有上升和下降。 第一遍,考虑上升的所以情况; 第二遍,考虑下降的所以情况。 然后对于波峰,用两边的max 值当成它的值即可。

    这样 思路变得更加清晰。 

     1 public class Solution {
     2     public int candy(int[] ratings) {
     3         // Note: The Solution object is instantiated only once and is reused
     4 //by each test case.
     5         int rLen = ratings.length;
     6         if (rLen == 0) return 0;
     7         int min = rLen; int give = 0;
     8         int[] gives = new int[rLen];
     9         for (int i = 1; i < rLen; i++) {
    10             if (ratings[i] > ratings[i - 1]) give++;
    11             else give = 0;
    12             gives[i] = give;
    13         }
    14         give = 0;
    15         for (int i = rLen - 2; i >= 0; i--) {
    16             if (ratings[i] > ratings[i + 1]) give++;
    17             else give = 0;
    18             min += Math.max(give, gives[i]);
    19         }
    20         min += gives[rLen - 1];
    21         return min;
    22     }
    23 }

     find out all local min rating, 
    for each local min rating, start with 1 candy, and expand on both directions
    until hit by local max.
    return total candies.

    O(n)

    第二遍: 波的方法, 左边走一次右边走一次。

     1 public class Solution {
     2     public int candy(int[] ratings) {
     3         // Note: The Solution object is instantiated only once and is reused by each test case.
     4         if(ratings == null || ratings.length == 0) return 0;
     5         int len = ratings.length;
     6         int[] candy = new int[len];
     7         int sum = 0;
     8         for(int i = 0; i < len; i ++)
     9             candy[i] = 1;
    10         for(int i = 1; i < len; i ++){
    11             if(ratings[i - 1] < ratings[i]) candy[i] = candy[i - 1] + 1;
    12         }
    13         for(int i = len - 1; i > 0; i --){
    14             if(ratings[i] < ratings[i - 1]) candy[i - 1] = Math.max(candy[i - 1], candy[i] + 1);
    15         }
    16         for(int i = 0; i < len; i ++)
    17             sum += candy[i];
    18         return sum;
    19     }
    20 }
  • 相关阅读:
    [机器学习]决策树
    [机器学习]Bagging and Boosting
    [机器学习]SVM原理
    [算法]排序算法综述
    天目山大峡谷和西天目山游记【转】
    西天目山出游攻略
    京东物流深度研究报告:京东物流VS亚马逊物流VS顺丰
    「数据标签体系」中台价值链路中“核心的核心”
    网络空间安全概论第一、四章笔记
    21牛客多校第一场
  • 原文地址:https://www.cnblogs.com/reynold-lei/p/3349915.html
Copyright © 2011-2022 走看看