[Leedcode][JAVA][按摩师][动态规划]
生活随笔
收集整理的這篇文章主要介紹了
[Leedcode][JAVA][按摩师][动态规划]
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【問題描述】
一個有名的按摩師會收到源源不斷的預約請求,每個預約都可以選擇接或不接。在每次預約服務之間要有休息時間,因此她不能接受相鄰的預約。給定一個預約請求序列,替按摩師找到最優的預約集合(總預約時間最長),返回總的分鐘數。注意:本題相對原題稍作改動示例 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. 動態規劃 二維狀態變量 由前往后 想清楚每一步
時間復雜度:O(N) 空間復雜度:O(N)
- dp[i][0] 表示:區間 [0,i] 里接受預約請求,并且下標為 i 的這一天不接受預約的最大時長;
- dp[i][1] 表示:區間 [0,i] 里接受預約請求,并且下標為 i 的這一天接受預約的最大時長。
- 今天不接受預約:或者是昨天不接受預約,或者是昨天接受了預約,取二者最大值,即:dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]);
- 今天接受預約:只需要從昨天不接受預約轉移而來,加上今天的時常,即:dp[i][1] = dp[i - 1][0] + nums[i]。
3.初始化
dp[0][0] = 0 與 dp[0][1] = nums[0];
優化:狀態數組多設置一行,以避免對極端用例進行討論
public class Solution {public int massage(int[] nums) {int len = nums.length;// dp 數組多設置一行,相應地定義就要改變,遍歷的一些細節也要相應改變// dp[i][0]:區間 [0, i) 里接受預約請求,并且下標為 i 的這一天不接受預約的最大時長// dp[i][1]:區間 [0, i) 里接受預約請求,并且下標為 i 的這一天接受預約的最大時長int[][] dp = new int[len + 1][2];// 注意:外層循環從 1 到 =len,相對 dp 數組而言,引用到 nums 數組的時候就要 -1for (int i = 1; i <= len; i++) {dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1]);dp[i][1] = dp[i - 1][0] + nums[i - 1];}return Math.max(dp[len][0], dp[len][1]);} }優化 [滾動數組] 三個變量 時間復雜度:O(N) 空間復雜度:O(1)
public class Solution {public int massage(int[] nums) {int len = nums.length;if (len == 0) {return 0;}if (len == 1) {return nums[0];}// dp[i & 1][0]:區間 [0, i] 里接受預約請求,并且下標為 i 的這一天不接受預約的最大時長// dp[i & 1][1]:區間 [0, i] 里接受預約請求,并且下標為 i 的這一天接受預約的最大時長int[][] dp = new int[2][2];dp[0][0] = 0;dp[0][1] = nums[0];for (int i = 1; i < len; i++) {dp[i & 1][0] = Math.max(dp[(i - 1) & 1][0], dp[(i - 1) & 1][1]);dp[i & 1][1] = dp[(i - 1) & 1][0] + nums[i];}return Math.max(dp[(len - 1) & 1][0], dp[(len - 1) & 1][1]);} }?###### 2. 動態規劃 一維狀態變量 由前往后 想清楚每一步
時間復雜度:O(N) 空間復雜度:O(N)
優化 [滾動數組] 三個變量 時間復雜度:O(N) 空間復雜度:O(1)
class Solution {public int massage(int[] nums) {int len = nums.length;if (len == 0) {return 0;}if (len == 1) {return nums[0];}// dp[i % 3]:區間 [0,i] 里接受預約請求的最大時長int[] dp = new int[3];dp[0] = nums[0];dp[1] = Math.max(nums[0], nums[1]);for (int i = 2; i < len; i++) {// 今天在選與不選中,選擇一個最優的dp[i % 3] = Math.max(dp[(i - 1) % 3], dp[(i - 2) % 3] + nums[i]);}return dp[(len - 1) % 3];} }【總結】
1.動態規劃流程
- 第 1 步:設計狀態
- 第 2 步:狀態轉移方程
- 第 3 步:考慮初始化
- 第 4 步:考慮輸出
- 第 5 步:考慮是否可以狀態壓縮
2.動態規劃 自底向上 狀態轉移
[一般編程] 自頂向下
[記憶化遞歸」隨時可能面對新問題
參考鏈接:https://leetcode-cn.com/problems/the-masseuse-lcci/solution/dong-tai-gui-hua-by-liweiwei1419-8/
總結
以上是生活随笔為你收集整理的[Leedcode][JAVA][按摩师][动态规划]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: R语言安装教程 | 图文介绍超详细
- 下一篇: [国密算法]一文了解国密算法