二、打家劫舍
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
示例 1:
输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。
示例 2:
输入:[2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
偷窃到的最高金额 = 2 + 9 + 1 = 12 。
1.Java解答
class Solution {
public int rob(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
int length = nums.length;
if (length == 1) {
return nums[0];
}
int first = nums[0], second = Math.max(nums[0], nums[1]);
for (int i = 2; i < length; i++) {
int temp = second;
second = Math.max(first + nums[i], second);
first = temp;
}
return second;
}
}
2.python解答
class Solution:
def rob(self, nums: List[int]) -> int:
if not nums:
return 0
size = len(nums)
if size == 1:
return nums[0]
first, second = nums[0], max(nums[0], nums[1])
for i in range(2, size):
first, second = second, max(first + nums[i], second)
return second
3.主要思想
动态规划思想
滚动数组:
滚动数组(Rolling Array)是一种优化算法中常用的技巧,用于在有限的存储空间内实现高效的数据处理。它主要用于降低空间复杂度,特别是在需要保存大量中间结果的情况下。
在传统的算法中,我们通常使用静态数组来存储数据。然而,对于某些问题,静态数组可能会占用大量的内存空间,尤其是当问题规模很大时。这时,滚动数组可以帮助我们节省内存,并在不丢失必要信息的情况下进行计算。
滚动数组的核心思想是重复利用数组中已经计算过的部分,通过覆盖或更新旧数据来存储新的数据。这样,我们只需要保持足够的存储空间来保存当前需要的数据,而不是保存所有数据。
下面举一个简单的例子来说明滚动数组的用法。假设我们要计算一个长度为N的斐波那契数列(Fibonacci Sequence),其中每个数是前两个数的和。传统的方法是使用一个静态数组来存储所有的中间结果,然后通过迭代计算得到最终的结果。这种方法的空间复杂度为O(N)。
而使用滚动数组的方法,我们只需要保存最近的两个数,而不是保存所有的中间结果。具体做法是,使用两个变量来存储当前计算的数和上一个计算的数,然后通过更新这两个变量来计算下一个数。这样,我们只需要O(1)的额外空间来存储这两个变量,大大降低了空间复杂度。
滚动数组的应用不仅限于斐波那契数列,还可以用于其他类型的问题,如动态规划、滑动窗口等。在这些问题中,滚动数组可以帮助我们在有限的存储空间内高效地处理数据,减少内存的占用。
需要注意的是,滚动数组的使用可能会增加代码的复杂性,因为我们需要维护变量之间的关系和更新逻辑。因此,在使用滚动数组时,我们需要仔细考虑问题的特性,并权衡空间和时间的复杂度。