题目描述
一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。在每次预约服务之间要有休息时间,因此她不能接受相邻的预约。给定一个预约请求序列,替按摩师找到最优的预约集合(总预约时间最长),返回总的分钟数。
注意:本题相对原题稍作改动
示例 1:
输入: [1,2,3,1]
输出: 4
解释: 选择 1 号预约和 3 号预约,总时长 = 1 + 3 = 4。
示例 2:
输入: [2,7,9,3,1]
输出: 12
解释: 选择 1 号预约、 3 号预约和 5 号预约,总时长 = 2 + 9 + 1 = 12。
示例 3:
输入: [2,1,4,5,3,1,1,3]
输出: 12
解释: 选择 1 号预约、 3 号预约、 5 号预约和 8 号预约,总时长 = 2 + 4 + 3 + 3 = 12。
题目分析求解
解
public static int massage(int[] nums) {
int a = 0, b = 0;
for (int num : nums) {
int c = Math.max(b, a + num);
a = b;
b = c;
}
return b;
}
运行过程
a=0 b=2 c=2 num=2
a=2 b=3 c=3 num=3
a=3 b=6 c=6 num=4
a=6 b=8 c=8 num=5
a=8 b=9 c=9 num=3
a=9 b=9 c=9 num=1
a=9 b=10 c=10 num=1
a=10 b=12 c=12 num=3
分析
1. 设置两个变量[a]保存上次求解最大值和当前次最大值[b]
2. 使用临时变量存储当前最大值max(b,a+num)
3. 分析逻辑: a = 之前已经确定了的最大值 b = 当前存储的最大值 c = 目前计算最大值 = max(b,a+num)
4. 根据3进行分析得出,[a] [b] [c] 为三个阶段的值,那么如果 b不大于 a+num那么计算的值就是 a 和 num的值为结果,从而跳过了b,如果b大于了a+num那么计算b的时候也跳过了a.因此只需要将b夹在中间,要么a+num,要么b直接作为当前最大值。
5. 以此迭代,始终将一个数组看作三个数来进行计算,那么最终就会得到响应的结果
总结
此类题型主要有两个方向考虑。
1. 将大问题看成小问题,题中提出需要间隔计算,那么最小单位就为3个元素,那么我们就按照三个元素进行计算,寻找一种可以迭代的方法就可以用小问题解决大问题了。
2. 此题还含有动态规划的感觉,因为在每一次计算时都用到了之前计算的值来进行迭代计算