如何使用递归正确退出House Robber实施?

时间:2018-07-19 16:37:34

标签: swift algorithm recursion iteration dynamic-programming

我正在做House Robber challenge

  

您是一名专业劫匪,打算在一条街道上抢劫房屋。   每个房子都藏有一定数量的钱,唯一的限制   阻止您抢劫每一个是相邻的房子有   安全系统已连接,它将自动与警察联系   如果同一晚晚上有两间相邻的房屋被闯入。

     

给出一个表示金额的非负整数列表   确定每间房子的最高金额   今晚不通知警察。

我的代码

class Solution {
    func rob(_ nums: [Int]) -> Int {
        var mostMoneyRobbed = 0

        func rob(neighborUnits: [Int], startfromUnit unit: Int, didRobAdjacentUnit: Bool, totalMoneyRobbed total: Int){

            if total > mostMoneyRobbed{
                mostMoneyRobbed = total
            }
            for i in unit...neighborUnits.count - 1{
                if i == neighborUnits.count - 1{
                    if !didRobAdjacentUnit{
                        if total + nums[i] > mostMoneyRobbed{                                
                            mostMoneyRobbed = total + nums[i]                                
                        }
                    }
                    return
                }

                if didRobAdjacentUnit{
                    rob(neighborUnits: nums, startfromUnit: unit + 1, didRobAdjacentUnit: false, totalMoneyRobbed: total)
                }else{
                    rob(neighborUnits: nums, startfromUnit: unit + 1, didRobAdjacentUnit: true, totalMoneyRobbed: total + nums[i])
                    rob(neighborUnits: nums, startfromUnit: unit + 1, didRobAdjacentUnit: false, totalMoneyRobbed: total)
                }
            }            
        }
        guard nums.count > 0 else {
            return 0
        }

        rob(neighborUnits: nums, startfromUnit: 0, didRobAdjacentUnit: true, totalMoneyRobbed: 0)
        rob(neighborUnits: nums, startfromUnit: 0, didRobAdjacentUnit: false, totalMoneyRobbed: 0)

        return mostMoneyRobbed
    }
}

用法:

let s = Solution()
print(s.rob([1,2,3])) // returns 5 instead of 4 

我的迭代策略是:

  • 如果先前的被抢劫了,那么我只能在下次迭代时抢劫。
  • 如果先前的没有被抢劫,那么我可以在下一次迭代时 抢劫或不抢劫。显然要找到所有我都做的有效抢劫!

我的退出策略在以下行中完成:

if i == neighborUnits.count - 1{

基本上,如果我到达单元末尾,迭代将停止。

然后,我将值与mostMoneyRobbed进行比较,如果值更大,则将其设置为该值。 在循环结束时,我只返回mostMoneyRobbed

但是,到达块的最后一个元素并返回我的代码后,继续进行!!!!我不明白为什么。它应该是很琐碎的

请注意,我不需要其他解决方案。我想修复自己的实现。

1 个答案:

答案 0 :(得分:2)

问题是我正在通过两种方法进行迭代。一个“ for循环”和unit + 1。我有点搞砸了递归的核心。只需要不使用'for循环'而仅使用unit + 1

class Solution {
    func rob(_ nums: [Int]) -> Int {
        var mostMoneyRobbed = 0

        func rob(neighborUnits: [Int], startfromUnit unit: Int, didRobAdjacentUnit: Bool, totalMoneyRobbed total: Int){

            if total > mostMoneyRobbed{
                mostMoneyRobbed = total
            }
            if unit == neighborUnits.count - 1{
                if !didRobAdjacentUnit{
                    if total + nums[unit] > mostMoneyRobbed{
                        mostMoneyRobbed = total + nums[unit]
                    }
                }
                return
            }

            if didRobAdjacentUnit{
                rob(neighborUnits: nums, startfromUnit: unit + 1, didRobAdjacentUnit: false, totalMoneyRobbed: total)
            }else{
                rob(neighborUnits: nums, startfromUnit: unit + 1, didRobAdjacentUnit: true, totalMoneyRobbed: total + nums[unit])
                rob(neighborUnits: nums, startfromUnit: unit + 1, didRobAdjacentUnit: false, totalMoneyRobbed: total)
            }
        }
        guard nums.count > 1 else{
            if nums.count == 0{
                return 0
            }else{
                return nums[0]
            }
        }

        rob(neighborUnits: nums, startfromUnit: 0, didRobAdjacentUnit: true, totalMoneyRobbed: 0)
        rob(neighborUnits: nums, startfromUnit: 0, didRobAdjacentUnit: false, totalMoneyRobbed: 0)

        return mostMoneyRobbed
    }
}

到目前为止,这已经按预期进行了。在LeetCode上,我在第49个测试用例上遇到了超过时间限制错误! :D

enter image description here