携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 6 天,点击查看活动详情
按摩师
原题地址
一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。在每次预约服务之间要有休息时间,因此她不能接受相邻的预约。给定一个预约请求序列,替按摩师找到最优的预约集合(总预约时间最长),返回总的分钟数。
注意:本题相对原题稍作改动
示例 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。
复制代码
思路分析
方法一
- 可以使用动态规划来解决该问题;
- 使用数组
res
中的 第i项 表示按摩师在接到第i个
预约时的最长时间数; - 来确定初值,第一项肯定为
nums[0]
,第二项为nums[0]
和nums[1]
中的最大值;第三项则为第一项+nums[2]
与第二项
的最大值; - 那么,
第i项
的最佳预约时间数即为第i-1项
与第i-2项+nums[i]
中的最大值; - 按照以上的规律来编写程序得到
res
的最终值; - 最后返回
res[nums.length - 1]
即可。
方法二
- 使用
res1
表示第i-1项
没有约到,使用res2
表示第i-1项
有约到; - 那么,对于
第i项
来说,约到的时长为res1 + nums[i]
,没约到的时长为res1
与res2
中的最大值; - 在计算完毕后,分别给
res1
和res2
赋值; - 循环结束后,取最大值即为最长的总时长。
AC 代码
方法一
/**
* @param {number[]} nums
* @return {number}
*/
var massage = function(nums) {
const len = nums.length
if(!len) return 0
let res = [nums[0], Math.max(nums[0], nums[1])]
for(let i = 2; i < len; i++) {
res[i] = Math.max(res[i - 2] + nums[i], res[i-1])
}
return res[len - 1]
};
复制代码
结果:
- 执行结果: 通过
- 执行用时:56 ms, 在所有 JavaScript 提交中击败了 86.30% 的用户
- 内存消耗:41.6 MB, 在所有 JavaScript 提交中击败了 5.48% 的用户
- 通过测试用例:69 / 69
方法二
/**
* @param {number[]} nums
* @return {number}
*/
var massage = function(nums) {
const len = nums.length
if(!len) return 0
let res1 = 0
let res2 = nums[0]
for (let i = 1; i < len; i++) {
let r = res1 + nums[i]
let n = Math.max(res1, res2)
res1 = n
res2 = r
}
return Math.max( res1, res2 )
};
复制代码
结果:
- 执行结果: 通过
- 执行用时:56 ms, 在所有 JavaScript 提交中击败了86.30%的用户
- 内存消耗:40.9 MB, 在所有 JavaScript 提交中击败了76.26%的用户
- 通过测试用例:69 / 69