打家劫舍
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 20 ms, 内存: 16.2 MB
/*
* 思路:
* 使用Java Stream API来实现同样的逻辑。由于Stream不适合直接用于修改数组,我们将使用递归结合Stream来计算最大偷窃金额。
*/
import java.util.stream.IntStream;
public class Solution {
public int rob(int[] nums) {
return IntStream.range(0, nums.length).map(i -> rob(nums, i, new int[nums.length])).max().orElse(0);
}
private int rob(int[] nums, int i, int[] memo) {
if (i < 0) return 0;
if (memo[i] != 0) return memo[i];
int result = Math.max(rob(nums, i - 1, memo), nums[i] + rob(nums, i - 2, memo));
memo[i] = result;
return result;
}
}
解释
方法:
这道题的题解采用了递归加备忘录的方法来求解。小偷有一个选择,他可以选择从当前的房子开始偷或者跳过一两个房子后再开始偷。基本的递归策略是:考虑当前位置c,小偷可以选择偷这个房子然后跳过下一个,直接从c+2开始或者从c+3开始(即不偷当前房子,也可能不偷下一个,但考虑后一个),或者不偷当前房子直接从c+1开始。结果是这些选择中可以偷到的最大金额。使用备忘录(cache)来存储已经计算过的结果,避免重复计算,提高效率。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
递归方法中,为什么选择从c+2或c+3开始而不是其他位置,如c+4或更远的位置?
▷🦆
在递归函数中,参数`money`没有在函数体中使用,它的目的是什么?是否是多余的?
▷🦆
备忘录`cache`中存储的是从当前位置开始能偷到的最大金额,那么如何确保计算时包含了所有可能的偷窃组合?
▷