代码随想录算法训练营第25天|134. 加油站、135. 分发糖果、860. 柠檬水找零

134. 加油站

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
		//贪心算法
		//定义一个数组balance表示从某站出发后到达下个站还有多少油,balance = gas - cost;
		int[] balance = new int[gas.length];
		for (int i = 0; i < balance.length; i++) {
			balance[i] = gas[i] - cost[i];
		}
		//贪心的地方:遍历balance数组,找到正值从当前站开始,向后移动,依次与后边的balance[i]相加
		//当和小于0时,证明中间会没油,说明从这中间的站开始都不能环路一周,继续向后寻找正值
		int startStation = -1;
		int curGas = 0;
		for(int i = 0; i < balance.length; i++){
			if(startStation == -1 && balance[i] >= 0){
				startStation = i;
				curGas += balance[i];
				continue;
			}
			if(startStation != -1){
				curGas += balance[i];
			}
			if(curGas < 0){
				startStation = -1;
				curGas = 0;
			}
		}
		for(int i = 0; i < startStation; i++){
			if(startStation != -1){
				curGas += balance[i];
			}
			if(curGas < 0){
				startStation = -1;
				curGas = 0;
			}
		}

		return startStation;

    }
}

——————————————————————————————————————————

135. 分发糖果 

 自己的思路:

从前向后遍历评分数组,对每个孩子尽可能都发1个糖果
如果当前孩子不能发一个糖果,那么在遍历过程中,肯定是因为前一个孩子的评分低于了当前遍历到的孩子评分
那么这时,这个孩子就要发比前一个孩子多一个的糖果。
如果遇见了当前遍历孩子的评分比上一个孩子的评分低的情况,然而上个孩子的糖果是1个,那么要向前,找到评分不大于前一个孩子评分的孩子,中间的糖果数量都加1

更合适的思路:

将问题分成两个维度处理

先从左到右处理右边分数更高的情况
再从右向左处理左边分数更高的情况

class Solution {
    public int candy(int[] ratings) {

		//int[] candyAllocate = new int[ratings.length];
		//
		//for(int i = 0; i < ratings.length; i++){
		//	if(i > 0 && ratings[i] > ratings[i - 1]){
		//		candyAllocate[i] = candyAllocate[i - 1] + 1;
		//	}else{
		//		candyAllocate[i] = 1;
		//	}
		//	int j = i;
		//	while(j > 0 && ratings[j - 1] > ratings[j] && candyAllocate[j - 1] <= candyAllocate[j]){
		//		candyAllocate[j - 1]++;
		//		j--;
		//	}
		//}
		int[] candyAllocate = new int[ratings.length];
		Arrays.fill(candyAllocate, 1);
		//先从左到右处理右边分数更高的情况
		//再从右向左处理左边分数更高的情况

		for (int i = 1; i < ratings.length; i++) {
			if(ratings[i] > ratings[i - 1]) candyAllocate[i] = candyAllocate[i - 1] + 1;
		}
		for (int i = ratings.length - 2; i >= 0; i--) {
			if(ratings[i] > ratings[i + 1]) candyAllocate[i] = Math.max(candyAllocate[i], candyAllocate[i + 1] + 1);
		}
		return Arrays.stream(candyAllocate).sum();
    }
}

——————————————————————————————————————————

860. 柠檬水找零 

 

贪心算法
如果要找零时,尽可能从大数额的零钱开始给 

class Solution {
    public boolean lemonadeChange(int[] bills) {
		int num5 = 0;
		int num10 = 0;
        for (int bill : bills) {
            if (bill == 5) {
                num5++;
            } else if (bill == 10) {
                if (num5 == 0) {
                    return false;
                }
                num10++;
                num5--;
            } else {
                if ((num10 == 0 && num5 < 3) || num5 == 0) {
                    return false;
                }
                if (num10 == 0) {
                    num5 -= 3;
                } else {
                    num10--;
                    num5--;
                }
            }
        }
		return true;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值