【LeetCode】LeetCode之打家劫舍Ⅱ——暴力递归+动态规划解决循环问题+DP空间优化
這道題和第 198 題相似,建議讀者首先閱讀「198. 打家劫舍」
🔒LeetCode之打家劫舍Ⅰ:LeetCode之打家劫舍Ⅰ
1.打家劫舍II 題目描述
你是一個專業的小偷,計劃偷竊沿街的房屋,每間房內都藏有一定的現金。這個地方所有的房屋都 圍成一圈 ,這意味著第一個房屋和最后一個房屋是緊挨著的。同時,相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警 。
給定一個代表每個房屋存放金額的非負整數數組,計算你 在不觸動警報裝置的情況下 ,今晚能夠偷竊到的最高金額。
💎示例 1:
輸入:nums = [2,3,2]
輸出:3
解釋:你不能先偷竊 1 號房屋(金額 = 2),然后偷竊 3 號房屋(金額 = 2), 因為他們是相鄰的。
💎示例 2:
輸入:nums = [1,2,3,1]
輸出:4
解釋:你可以先偷竊 1 號房屋(金額 = 1),然后偷竊 3 號房屋(金額 = 3)。
偷竊到的最高金額 = 1 + 3 = 4 。
💎示例 3:
輸入:nums = [0]
輸出:0
📜提示:
- 1 <= nums.length <= 100
- 0 <= nums[i] <= 1000
2.打家劫舍Ⅱ思路分析
🔗直達打家劫舍①鏈接,默認讀者已經搞懂了打家劫舍①.
該問題是在打家劫舍①的基礎上,添加了一個循環結構。如果你已經理解了打家劫舍①,那么這個Ⅱ只需要考慮怎么解決這個循環問題即可,也就是第一個數據和最后一個數據不能同時出現,要么最大金額只包含第一個數據,要么只包含最后一個數據。
所以我們可以將數組分為兩部分,各自找出每一部分的最大金額,然后返回它們兩個金額最大的即可【你會發現這樣分為兩部分之后,就不會出現第一個和最后一個數據同時出現的問題了;然后每一部分的解題過程就和打家劫舍1一模一樣了。
3.暴力解法-遞歸實現
📕流程
(1)將數組分為兩部分即可
- 0 ~ n - 1
- 1 ~ n
(2)然后將每一部分按照打家劫舍Ⅰ求解即可
(3)返回這兩部分結果的最大值
當我將該暴力解法提交到LeetCode,發現會超時。
從上圖我們可以看出使用遞歸出現了大量的重復計算(我只是枚舉前三行,越往后重復越多),這是遞歸比較忌諱的問題之一(重復和棧溢出)。這樣無異于在浪費CPU的運算單元。
復雜度分析:
空間復雜度:O(n)【每個??臻g復雜度為O(1)】O(n*1)=O(n)
時間復雜度:O(n^n)
- 遞歸算法的空間復雜度與所生成的最大遞歸樹的深度成正比。如果遞歸算法的每個函數調用都占用 O(m) 空間,并且如果遞歸樹的最大深度為 n,則遞歸算法的空間復雜度將為 O(n·m)?!?/li>
💌上述中遞歸解題方式的缺點就是重復量比較多,所以我們可以可以將途中計算的結果保存下來,俗稱記憶集或記憶化搜索。此時你應該想到這不正是動態規劃嘛。
4.記憶化搜索-動態規劃
需要兩個dp數組進行保存,因為在抽象層面分為兩個數組了嘛,所以要使用兩個記憶集。其他就和打家劫舍1一樣了。
循環體內部包含兩部分
- 0 ~ n-1
- 1 ~ n
復雜度分析
空間復雜度為O(n)
時間復雜度為O(n)
當我提交LeetCode上時,可以發現通過了。
分析一下:能不能將空間復雜度優化成O(1)呢?
5.動態規劃之優化空間復雜度
如果理解了打家劫舍1和前面的流程,這個應該很簡單。
public int rob3(int[] nums) {if (nums.length == 1) {return nums[0];}if (nums.length == 2) {return Math.max(nums[0], nums[1]);}int pre1 = nums[0], pre2 = nums[1];int suf1 = Math.max(nums[0], nums[1]);int suf2 = Math.max(nums[1], nums[2]);int maxMoney1 = suf1;int maxMoney2 = suf2;for (int i = 2; i < nums.length - 1; i++) {maxMoney1 = Math.max(pre1 + nums[i], suf1);pre1 = suf1;suf1 = maxMoney1;maxMoney2 = Math.max(pre2 + nums[i + 1], suf2);pre2 = suf2;suf2 = maxMoney2;}return Math.max(maxMoney1, maxMoney2);}復雜度分析
時間復雜度:O(n)
空間復雜度:O(1)
提交到LeetCode,當然能通過
總結
以上是生活随笔為你收集整理的【LeetCode】LeetCode之打家劫舍Ⅱ——暴力递归+动态规划解决循环问题+DP空间优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【LeetCode】LeetCode之打
- 下一篇: 【LeetCode】LeetCode之删