LeetCode刷题——打家劫舍#198#Medium

打家劫舍题目的思路探讨与源码
    打家劫舍的题目如下图,该题属于动态规划和数组类型的题目,主要考察对于动态规划和数组的使用理解和认识。本文的题目作者想到2种方法,分别是递归方法和动态规划方法,其中递归方法使用java进行编写,而动态规划方法使用Python进行编写,当然这可能不是最优的解法,还希望各位大佬给出更快的算法。
在这里插入图片描述
    本人认为该题目可以使用递归的算法,首先我们获取数组的长度,并且初始化一个Map方便后续的存储。然后调用递归函数calMax方法,令下标等于最后一位,如果下标小于0则结束递归。首先判断Map里面有没有当前位置前两位的下标,如果有则最终值是当前位置前两位的值,否则的话就继续调用递归函数calMax,并且把当前位置前两位的值和下标记录下来,然后再去访问当前位置的前面一个位置和它的值,思路和前面一样,那么按照这个思路我们的Java代码如下:

#喷火龙与水箭龟
class Solution {
    public int rob(int[] nums) {
    Map<Integer,Integer> kv = new HashMap<>();
	int len = nums.length-1;
    return calMax(nums,len,kv);
    }
    public int calMax(int[] nums,int jr,Map<Integer,Integer> kv) {
    if(jr<0)
        return 0;
    int finalNum = 0;
    int maxNum = 0;
    if (kv.containsKey(jr-2))
        finalNum = kv.get(jr-2);
    else {
        finalNum = calMax(nums,jr-2,kv);
        kv.put(jr-2,finalNum);
    }
    if (kv.containsKey(jr-1))
        maxNum = kv.get(jr-1);
    else {
        maxNum = calMax(nums,jr-1,kv);
        kv.put(jr-1,maxNum);
    }
    int index = finalNum + nums[jr];
    return Math.max(maxNum,index);
}
}

在这里插入图片描述
    显然,我们还可以使用动态规划的方法来进行解决,首先看两种特殊情况,第一种是数组长度为0,那么直接返回0,第二种是数组长度是1,那么直接返回第一个值即可。然后开始一般情况的讨论,我们把第一个元素记为a,第一个元素和第二个元素的最大值记为b,然后从第三个元素开始遍历,把b值记录,然后计算a与当前下标的值的和与b的最大值赋值给b,然后把原来的b值赋值给a,最终返回b的值,所以根据这个思路就可以写出代码,下面是Python代码部分:

#喷火龙与水箭龟
class Solution:
    def rob(self, nums: List[int]) -> int:
        lenNums = len(nums)
        if nums is None:
            return 0 
        if lenNums == 1:
            return nums[0]
        a = nums[0]
        b = max(nums[0], nums[1])
        for jr in range(2,lenNums):
            t = b
            b = max(a+nums[jr],b)
            a = t
        return b

在这里插入图片描述
    从结果来说java版本的递归方法和python版本的动态规划速度都非常不错,应该是有更多的方法可以进一步提速的,希望朋友们能够多多指教,非常感谢。

おすすめ

転載: blog.csdn.net/qq_26727101/article/details/118650883