前端刷题路-Day32:按摩师(题号不确定)

206 阅读2分钟

按摩师(题号不确定)

题目

一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。在每次预约服务之间要有休息时间,因此她不能接受相邻的预约。给定一个预约请求序列,替按摩师找到最优的预约集合(总预约时间最长),返回总的分钟数。

注意:本题相对原题稍作改动

示例 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

解释

经典动态规划,比较简单的一题,用来回忆动态规划再合适不过了。

这题和买卖股票需要休息一天有点类似,不过更加简单一点,不需要做减法处理,直接取值相加即可。

因为需要休息一天,所以DP状态可以为:

DP[i][当天不预约] = Math.max(DP[i - 1][当天预约], DP[i - 1][当天不预约])
DP[i][当天预约] = DP[i - 1][当天不预约] + 当天预约时间

或者可以转化成单个数组,这里初始值就需要多赋值一次了,循环从2开始,可以直接确定当天的最多预约时间。

DP[i] = Math.max(DP[i - 2] + 当天预约时间, DP[i - 1])

两种方法都可以,差别不大。

自己的答案(双数组)

var massage = function(nums) {
  var len = nums.length
      arrHas = new Array(len)
      arrNone = new Array(len)
  if (!len) return 0
  arrHas[0] = nums[0]
  arrNone[0] = 0
  for (let i = 1; i < len; i++) {
    arrHas[i] = arrNone[i - 1] + nums[i]
    arrNone[i] = Math.max(arrHas[i - 1], arrNone[i - 1])
  }
  return Math.max(arrHas[len - 1], arrNone[len - 1])
};

也是比较简单,arrHas数组表示当天预约的情况,arrNone表示当天休息的情况,最后去二者最后一个元素的最大值即可。

自己的答案(降维)

var massage = function(nums) {
  var len = nums.length
      order = nums[0]
      rest = 0
  if (!len) return 0
  for (let i = 1; i < len; i++) {
    [order, rest] = [rest + nums[i], Math.max(order, rest)]
  }
  return Math.max(order, rest)
};

通过上面的答案可以得出,其实只需要记录前一天休息和预约的两种不同状态即可,所以直接提取成两个变量,order代表前一天预约了,rest代表前一天休息了。

每次循环时使用解构赋值来更新orderrest,省去了中间步骤的情况。

使用解释里面的第二个DP公式也可以,只是计算当天的公式需要简单变化下,问题不大。



PS:想查看往期文章和题目可以点击下面的链接:

这里是按照日期分类的👇

前端刷题路-目录(日期分类)

经过有些朋友的提醒,感觉也应该按照题型分类
这里是按照题型分类的👇

前端刷题路-目录(题型分类)

有兴趣的也可以看看我的个人主页👇

Here is RZ