来自Leetcode第213题打家劫舍II
你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。
示例 1:
1 | 输入: [2,3,2] |
动态规划
环状排列意味着第一个房子和最后一个房子中只能选择一个偷窃,因此可以把此环状排列房间问题约化为两个单排排列房间子问题:
- 在不偷窃第一个房子的情况下(即 nums[1:]),最大金额是 p1 ;
- 在不偷窃最后一个房子的情况下(即 nums[:n−1]),最大金额是 p2 。
- 综合偷窃最大金额: 为以上两种情况的较大值,即 max(p1,p2) 。
记:
f(k) = 从前 k 个房屋中能抢劫到的最大数额,Ai = 第 i 个房屋的钱数。
首先看 n = 1
的情况,显然 f(1) = A1。
再看 n = 2
,f(2) = max(A1, A2)。
对于 n = 3
,有两个选项:
- 抢第三个房子,将数额与第一个房子相加。
- 不抢第三个房子,保持现有最大数额。
显然,你想选择数额更大的选项。于是,可以总结出公式:
f(k) = max(f(k – 2) + A_k, f(k – 1))
1 | public int rob(int[] nums) { |