面试必备算法题集之「动态规划」Ⅰ
題目來源:LeetCode-騰訊-動態規劃
題庫鏈接:LeetCode傳送門
前言
這份題集來源于 LeetCode-騰訊-動態規劃 ,懷著想學習動態規劃的心(帶著害怕面試被問到的恐懼 )做了第一份DP題集,希望可以志同道合的伙伴可以共同進步。
文章目錄
- 前言
- 1. 爬樓梯
- 2. 最大子序列和
- 3. 買賣股票的最佳時機
- 4. 買賣股票的最佳時機 II
- 5. 不同路徑
- 6. 子集
- 總結
1. 爬樓梯
假設你正在爬樓梯。需要 n 階你才能到達樓頂。
每次你可以爬 1 或 2 個臺階。你有多少種不同的方法可以爬到樓頂呢?
注意:給定 n 是一個正整數。
示例 1:
輸入: 2
輸出: 2
示例 2:
輸入: 3
輸出: 3
狀態轉移方程:dp[i]=dp[i?1]+dp[i?2]dp[i] = dp[i-1]+dp[i-2]dp[i]=dp[i?1]+dp[i?2]
class Solution {public int climbStairs(int n) {if (n == 1) {return 1;} else if (n == 2) {return 2;}int a = 1, b = 2;for (int i = 2; i < n; i++) {b = a + b;a = b - a;}return b;} }2. 最大子序列和
給定一個整數數組 nums ,找到一個具有最大和的連續子數組(子數組最少包含一個元素),返回其最大和。
示例:
輸入: [-2,1,-3,4,-1,2,1,-5,4],
輸出: 6
解釋: 連續子數組 [4,-1,2,1] 的和最大,為 6。
狀態轉移方程:dp[i]=max(dp[i?1]+nums[i],nums[i])dp[i]=max(dp[i-1]+nums[i], nums[i])dp[i]=max(dp[i?1]+nums[i],nums[i])
PS: dp[i]dp[i]dp[i] 表示的是以nums[i]nums[i]nums[i]結尾的子序列的最大值
3. 買賣股票的最佳時機
給定一個數組,它的第 i 個元素是一支給定股票第 i 天的價格。
如果你最多只允許完成一筆交易(即買入和賣出一支股票一次),設計一個算法來計算你所能獲取的最大利潤。
注意:你不能在買入股票前賣出股票。
示例 1:
輸入: [7,1,5,3,6,4]
輸出: 5
解釋: 在第 2 天(股票價格 = 1)的時候買入,在第 5 天(股票價格 = 6)的時候賣出,最大利潤 = 6-1 = 5 。
示例 2:
輸入: [7,6,4,3,1]
輸出: 0
解釋: 在這種情況下, 沒有交易完成, 所以最大利潤為 0。
狀態轉移方程:dp[i]=max(dp[i?1],prices[i]?minPrice)dp[i] = max(dp[i-1],prices[i]-minPrice)dp[i]=max(dp[i?1],prices[i]?minPrice)
PS:其中 minPriceminPriceminPrice 表示 i 天前的最低價格。
4. 買賣股票的最佳時機 II
給定一個數組,它的第 i 個元素是一支給定股票第 i 天的價格。
設計一個算法來計算你所能獲取的最大利潤。你可以盡可能地完成更多的交易(多次買賣一支股票)。
注意:你不能同時參與多筆交易(你必須在再次購買前出售掉之前的股票)。
示例 1:
輸入: [7,1,5,3,6,4]
輸出: 7
解釋: 在第 2 天(股票價格 = 1)的時候買入,在第 3 天(股票價格 = 5)的時候賣出, 這筆交易所能獲得利潤 = 5-1 = 4 。隨后,在第 4 天(股票價格 = 3)的時候買入,在第 5 天(股票價格 = 6)的時候賣出, 這筆交易所能獲得利潤 = 6-3 = 3 。
狀態轉移方程(根據上面的樹形圖推導):
dp[i][0]=max(dp[i?1][0],dp[i?1][1]+prices[i])dp[i][1]=max(dp[i?1][1],dp[i?1][0]?prices[i])dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i])\\ dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]) dp[i][0]=max(dp[i?1][0],dp[i?1][1]+prices[i])dp[i][1]=max(dp[i?1][1],dp[i?1][0]?prices[i])
PS:dp[i][0]dp[i][0]dp[i][0]表示第 i 天持有的現金的最大利潤,dp[i][1]dp[i][1]dp[i][1]表示第 i 天持有的股票的最大利潤。
可以看一下這篇題解:暴力搜索、貪心算法、動態規劃
(明明貪心就很好做……)
5. 不同路徑
一個機器人位于一個 m x n 網格的左上角 (起始點在下圖中標記為“Start” )。
機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角(在下圖中標記為“Finish”)。
問總共有多少條不同的路徑?
示例 1:
輸入: m = 3, n = 2
輸出: 3
解釋:
從左上角開始,總共有 3 條路徑可以到達右下角。
示例 2:
輸入: m = 7, n = 3
輸出: 28
狀態轉移方程:dp[i][j]=dp[i?1][j]+dp[i][j?1]dp[i][j] = dp[i - 1][j] + dp[i][j-1]dp[i][j]=dp[i?1][j]+dp[i][j?1]
class Solution {public int uniquePaths(int m, int n) {int[][] dp = new int[n][m];for (int i = 0; i < n; i++) {dp[i][0] = 1;}for (int i = 0; i < m; i++) {dp[0][i] = 1;}for (int i = 1; i < n; i++) {for (int j = 1; j < m; j++) {dp[i][j] = dp[i - 1][j] + dp[i][j - 1];}}return dp[n - 1][m - 1];} }(明明排列組合更加方便……)
6. 子集
給定一組不含重復元素的整數數組 nums,返回該數組所有可能的子集(冪集)。
說明:解集不能包含重復的子集。
示例:
輸入: nums = [1,2,3]
輸出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
狀態轉移方程:set[k]=set[j]+nums[i]set[k] = set[j] + nums[i]set[k]=set[j]+nums[i]
PS:其中 set[k]set[k]set[k] 表示新找的一個集合, set[j]set[j]set[j] 表示原先找到的集合, nums[i]nums[i]nums[i] 表示新的數字。
不知道為啥這道題在動態規劃題單里面……(大霧 )
總結
終于寫完了,感覺很多題就用不著去DP,直接貪心就好了,強行DP做到我裂開。由于時間緊迫,題解也沒有寫得很詳細,就將就著看吧,有問題可以留言提出來哦~
總結
以上是生活随笔為你收集整理的面试必备算法题集之「动态规划」Ⅰ的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手撕设计模式之「单例模式」(详细解析)
- 下一篇: 图解排序算法之谈「选择排序」