【发布时间】:2021-07-25 11:06:55
【问题描述】:
这是一个关于 leetcode 的问题 House Robber 的 memoization 方法的问题。 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, 0, 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 的路径产生的战利品。这是正确的吗?这对我来说似乎不对。
【问题讨论】:
-
我用问题的链接更新了描述
-
@DanielHao 这个评论对我来说毫无意义:哪个公式?备忘录是不必要的?凭什么?这里有重叠的问题。是什么让记忆变得不必要?仅仅因为我必须解决的问题是 n+1 和 n+2,这并不能使它等同于斐波那契数列。尽管如此,斐波那契数列确实使用记忆来提高其性能。究竟什么更快?一遍又一遍地解决同样的问题——考虑到记忆是不可能的。
-
请不要依赖链接来解释您的问题。在链接中包含问题的文本,或在此处的问题正文中包含其他一些完整的描述。
-
在Leetcode House robber查看更简单的代码
-
doRob(nums, i, memo)计算可获得的最大战利品假设我们只访问编号为i或更大的房屋的一部分。 房屋i不是必需的访问过——只有编号小于i的房屋都没有。
标签: algorithm dynamic-programming memoization