本文主要是介绍leetcode刷题(93)——213. 打家劫舍 II,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。
示例 1:
输入: [2,3,2]
输出: 3
解释: 你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。
示例 2:
输入: [1,2,3,1]
输出: 4
解释: 你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。偷窃到的最高金额 = 1 + 3 = 4 。
这道题目和第一道描述基本一样,强盗依然不能抢劫相邻的房子,输入依然是一个数组,但是告诉你这些房子不是一排,而是围成了一个圈。
也就是说,现在第一间房子和最后一间房子也相当于是相邻的,不能同时抢。比如说输入数组 nums=[2,3,2],算法返回的结果应该是 3 而不是 4,因为开头和结尾不能同时被抢。
首先,首尾房间不能同时被抢,那么只可能有三种不同情况:要么都不被抢;要么第一间房子被抢最后一间不抢;要么最后一间房子被抢第一间不抢。
这三种情况,那种的结果最大,就是最终答案呗!不过,其实我们不需要比较三种情况,只要比较情况二和情况三就行了,因为这两种情况对于房子的选择余地比情况一大呀,房子里的钱数都是非负数,所以选择余地大,最优决策结果肯定不会小。
class Solution {public int rob(int[] nums) {int n = nums.length;if (n == 1) return nums[0];int one = find(nums,0,n-2);int two = find(nums,1,n-1);return Math.max(one,two);}public int find(int nums[],int start,int end){//记录dp[i+1] int len1=0;//记录dp[i+2]int len2=0;// 记录 dp[i]int dp = 0;for(int i = end;i>=start;i--){dp = Math.max(nums[i]+len2,len1);len2 = len1;len1 = dp;}return dp;}
}
这篇关于leetcode刷题(93)——213. 打家劫舍 II的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!