如何解决盗贼记忆
这是一个关于 leetcode 的问题房屋强盗的记忆方法的问题。 Here you may find the actual description of the problem。
您是一名职业劫匪,计划抢劫街道上的房屋。 每间房子都藏着一定的钱,唯一的约束 阻止你抢劫他们中的每一个是相邻的房子有 安全系统已连接,它会自动联系 如果两个相邻的房子在同一天晚上被闯入,警方就会报警。
给定一个整数数组 nums 代表每个人的钱数 房子,把你今晚能抢劫的最大金额还给你 报警。
输入:nums = [1,2,3,1]
输出:4
解释:抢房子1(钱=1) 然后抢劫房子3(钱= 3)。
您可以抢劫的总金额 = 1 + 3 = 4.
以下是在 leetcode 上使用 memoization 获得最高投票的答案
int rob(int[] nums) {
int[] memo = new int[nums.length];
Arrays.fill(memo,-1);
return doRob(nums,memo);
}
private int doRob(int[] nums,int index,int[] memo) {
if (index >= nums.length) return 0;
if (memo[index] == -1)
memo[index] = Math.max(nums[index] + doRob(nums,index + 2,memo),doRob(nums,index + 1,memo));
return memo[index];
}
如您所见,每次迭代都有两个选项
- 要么抢房子,然后继续下一个不相邻的房子
- 不要抢劫房子,继续相邻的房子
为了提高时间复杂度,我们有一个记忆数组,从每个房子开始携带最大战利品 - 至少这是解决方案所声称的。
我不明白以下几点:如果我们决定不抢劫房子 i
并沿着这条路走下去,我们会意识到 doRob(nums,i + 2) + nums[i] < doRob(nums,i + 1)
。因此,换句话说,我们意识到当我们决定不抢劫房屋i
时采取的路径比做抢劫房子后采取的路径产生更高的战利品。然后我们将设置memo[i] = doRob(nums,i + 1)
。因此,我们将从索引 i
开始的最大战利品分配给不包括房屋 i
的路径产生的战利品。这是正确的吗?我觉得不太合适。
解决方法
是的,你对代码的理解是正确的,是的,代码是正确的。
该代码实际上是反向工作的,并计算从递归深处的街道尽头到连续返回时的开头可能的最高战利品。
假设一条有可用资金的“街道” 1,7,2,... 并考虑使用更简单的算法,没有不必要的递归。
那么三宫初始段的最大战利品可能是7,这确实不包括来自第三宫的钱。这是因为小偷没有义务进入每个其他房子。
例如,对于像 1,1,10,1 这样的输入,抢劫第三或第四家将排除 7 或 10,因此会降低最终结果。所以,当我们考虑 10 的第 5 宫时,我们需要考虑前三宫的 7,即使它不包括来自第三宫的钱。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。