问题描述
在猫星球上,小R负责给一行排队的猫分发鱼干。每只猫有一个等级,等级越高的猫应该得到更多的鱼干。规则如下:
- 每只猫至少得到一斤鱼干。
- 如果一只猫的等级高于它相邻的猫,它就应该得到比相邻的猫更多的鱼干。
小R想知道,为了公平地满足所有猫的等级差异,他至少需要准备多少斤鱼干。
测试样例
样例1:
输入:
n = 3, cats_levels = [1, 2, 2]
输出:4
样例2:
输入:
n = 6, cats_levels = [6, 5, 4, 3, 2, 16]
输出:17
样例3:
输入:
n = 20, cats_levels = [1, 2, 2, 3, 3, 20, 1, 2, 3, 3, 2, 1, 5, 6, 6, 5, 5, 7, 7, 4]
输出:35
算法思路
- 题目要求猫如果等级比邻居高,那么分配的鱼干也要比邻居多,这就涉及到了左右的比较。我们可以把左右的比较拆开来,先和左边的比较,然后再返过来和右边的比较。
- 首先,用一个for循环从左向右遍历,如果当前这只猫的等级比它左边的猫高,那么当前这只猫的鱼干就要比左边那只猫多一斤(因为要求最少的鱼干,所以我们只给多一斤,贪心的体现),如果等级和左边的猫相等或者比左边的猫小,不做处理,还是一斤。我们这一轮循环主要解决左边的猫比当前猫等级大的情况。遍历完成之后,就确保了,每一只猫,如果左边的猫比自己等级小,鱼干一定比自己少。
- 接着,再用一个for循环从右向左遍历,如果当前这只猫的等级比它右边的猫高。那么当前这只猫的鱼干至少要比右边那只猫多一斤,但是我们还要保持如果比左边的猫等级高,当前猫的鱼干也要比左边多,所以我们要在当前猫已经有的鱼干和比右边那只猫的鱼干多一斤这两个数量中取最大值,这样才能同时满足猫如果等级比左右邻居高,那么分配的饼干也要比左右邻居多。遍历完成之后,就确保了,每一只猫,如果右边的猫比自己等级小,鱼干一定比自己少。
- 两个循环遍历下来,我们已经解决了猫的鱼干数量问题,最后统计一下每只猫的鱼干,累加起来就是所需鱼干的最小总数了。
代码实现
public static int solution(int n, List<Integer> catsLevels) {
// Please write your code here
/*
思路:遍历两次,第一次只考虑左边的邻居,第二次只考虑右边的邻居,两次选取最大值就是最终应该分配的鱼干
*/
int[] rightnum = new int[catsLevels.size()];
rightnum[0] = 1;
for(int i =1 ;i<catsLevels.size();i++){
if(catsLevels.get(i)>catsLevels.get(i-1)){
rightnum[i] = rightnum[i-1] +1;
}else{
rightnum[i] = 1;
}
}
int[] leftnum = new int[catsLevels.size()];
leftnum[catsLevels.size()-1] = rightnum[catsLevels.size()-1];
int total = leftnum[catsLevels.size()-1];
for(int i = catsLevels.size()-2;i>=0;i--){
if(catsLevels.get(i)>catsLevels.get(i+1)){
leftnum[i] = leftnum[i+1]+1;
}else{
leftnum[i] = 1;
}
total = total +Math.max(leftnum[i], rightnum[i]);
}
return total;
}