LeetCode 算法:按摩师

携手创作,共同成长!这是我参与「掘金日新计划 · 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复制代码

思路分析

方法一

  1. 可以使用动态规划来解决该问题;
  2. 使用数组 res 中的 第i项 表示按摩师在接到 第i个 预约时的最长时间数;
  3. 来确定初值,第一项肯定为 nums[0],第二项为 nums[0]nums[1] 中的最大值;第三项则为 第一项+nums[2]第二项 的最大值;
  4. 那么,第i项 的最佳预约时间数即为 第i-1项第i-2项+nums[i] 中的最大值;
  5. 按照以上的规律来编写程序得到 res 的最终值;
  6. 最后返回 res[nums.length - 1] 即可。

方法二

  1. 使用 res1 表示 第i-1项 没有约到,使用 res2 表示 第i-1项 有约到;
  2. 那么,对于 第i项 来说,约到的时长为 res1 + nums[i],没约到的时长为 res1res2 中的最大值;
  3. 在计算完毕后,分别给 res1res2 赋值;
  4. 循环结束后,取最大值即为最长的总时长。

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

END

猜你喜欢

转载自juejin.im/post/7127643734912532494