【问题标题】:How to use memoization in my code?如何在我的代码中使用记忆?
【发布时间】:2017-11-21 20:28:09
【问题描述】:

我有一个问题陈述如下: 你是一名专业的强盗,计划抢劫沿街的房屋。每栋房子都藏有一定数量的钱,唯一阻止你抢劫的限制是相邻的房子都连接了安全系统,如果同一晚上有两栋相邻的房子被闯入,它会自动联系警察。

给定一个代表每个房子里的钱的非负整数列表,确定你今晚可以在不报警的情况下抢劫的最大金额。

我正在用 Java 编写代码。我正在使用动态编程来解决这个问题,代码给了我正确的解决方案。但是,代码效率不高,因为我使用递归而不是使用记忆来解决问题。我如何在这段代码中使用记忆的概念来提高我的代码效率?这是我的代码:

class Solution {

    public int rob(int[] nums) {
        return robmax(nums,nums.length-1);    
    }

    public int robmax(int[] nums,int n) {
        int max = 0;
        if(nums.length==0) return 0;
        if(n==1) return Math.max(nums[0],nums[1]);
        if(n==0) return nums[0];
        else{
            max = Math.max(nums[n]+robmax(nums,n-2),robmax(nums,n-1));
        }
        return max;
    }
}

另外,我的算法的运行时间复杂度是多少。

【问题讨论】:

  • memon 值的数组初始化为 -1 以表示数组中的任何内容。函数的第一行应该检查 memo[n] 是否 memo[n]。然后修改您的函数以将计算结果存储在memo[n] 中。至于您的复杂性,我相信您的原始形式是O(phi^n),其中phi=1.618..。请参阅关于斐波那契数列的讨论以了解原因。对于记忆形式,请自己尝试。
  • 你试过什么?我觉得这些天问的大多数问题只是人们的功课......
  • 你想记住什么?
  • 这是交给我的任务。

标签: java algorithm dynamic-programming memoization


【解决方案1】:

你不需要记忆来解决这个问题, 或递归调用。 动态编程 解决方案将工作得很好而且更简单。 您可以通过一次遍历元素找到解决方案。 考虑这个算法:

  • max初始化为0
  • 对于每座房屋,您可以抢劫的最大值为:
    • 截至house[i-2]的最大值+当前房屋的价值
    • 截至house[i-1]的最大值

也就是说,跟踪前一宫和前一宫的已知最大值。 当您到达最后一所房子时,您将获得累积的最大金额。 这是大纲,我希望我不会破坏练习:

public int rob(int[] nums) {
    int max = 0;
    int prev = 0;
    int prevprev = 0;
    for (int current : nums) {
        // TODO: 3 lines to solve the puzzle
    }
    return max;
}   

【讨论】:

  • 我同意。我几乎发布了这个。但这不是 OP 的问题。
  • 我想使用记忆。您的解决方案只使用 dp.无论如何,谢谢
  • @user45437 够公平的。我担心由于内存需求(O(n) 而不是最佳的O(1)),memoization 解决方案不会给出通过结果。其他人已经在评论中给了你一个记忆策略,所以如果我现在将它添加到我的答案中是不合适的。我知道这不是您想要的,这很好。
猜你喜欢
  • 2019-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-25
  • 2014-06-18
  • 1970-01-01
  • 2012-09-22
  • 2017-07-29
相关资源
最近更新 更多