LeetCode 135、860

159 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情

题目:本文包含以下几题:

  1. n个孩子站成一排,给定一个数组表示每个孩子的评分,按照要求,每个孩子至少一个糖果,相邻的两个孩子分高的可以获得更多糖果,计算最少糖果数目。
  2. 柠檬水找钱,每杯柠檬水5块,顾客会给5、10、20来付钱,你需要找给顾客相应的钱,问给定序列是否可以完成找钱。

解题思路

LeetCode 135、分发糖果

解决本题最重要的是不能同时看两边,如果先看一个孩子的左边再看一个孩子的右边,那必然导致顾此失彼,导致逻辑混乱。

我们可以将问题进行拆分,首先是每个孩子至少一颗糖,但如果当前孩子比左边孩子的分更大,则糖果增加,依次类推,我们就可以得到一个按照从左往右满足条件的糖果序列。

上面已经看了当前孩子和左边孩子的糖果序列,那在此基础上还需要注意当前孩子和右边孩子的糖果序列,此时我们需要根据糖果的数量来更新,因为可能当前孩子的糖果已经大于右边孩子的了(根据前一个序列),可得代码如下:

public int candy(int[] ratings) {
    int len = ratings.length;
    int[] res = new int[len];
    Arrays.fill(res, 1);
    for(int i=1;i<len;i++){
        if(ratings[i]>ratings[i-1]) res[i] = res[i-1] + 1;
    }
    for(int i=len-2;i>=0;i--){
        if(ratings[i]>ratings[i+1]) res[i] = Math.max(res[i], res[i+1] + 1);
    }
    int value = 0;
    for (int re : res) {
        value += re;
    }
    return value;
}

LeetCode 860 柠檬水找钱

本题是比较简单的一题,如果序列首元素不是5,那必然不能正确找钱,之后我们只需要统计5块和十块的数量,当遇到10块就判断是否可以用当前五块进行正确找零,20则分两种情况:全看五块或者既看五块又看十块。

可得代码如下:

public boolean lemonadeChange(int[] bills) {
    if(bills[0]!=5) return false;
    int curF = 0;
    int curT = 0;
    for(int i=0;i<bills.length;i++){
        if(bills[i]==5) {
            curF++;
        }else if(bills[i]==10){
            curT++;
            curF--;
            if(curF<0) return false;
        }else {
            if(curT>0&&curF>0){
                curT--;
                curF--;
            }else if(curF>=3) {
                curF -= 3;
            }else {
                return false;
            }
        }
    }
    return true;
}