当前位置: 面试刷题>> 打家劫舍(经典算法150题)


题目描述

打家劫舍

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警

给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额

示例

示例 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 。

PHP 代码示例

function rob($nums) {
    $n = count($nums);
    if ($n === 0) {
        return 0;
    }
    if ($n === 1) {
        return $nums[0];
    }
    
    $dp = array_fill(0, $n, 0);
    $dp[0] = $nums[0];
    $dp[1] = max($nums[0], $nums[1]);
    
    for ($i = 2; $i < $n; $i++) {
        $dp[$i] = max($dp[$i-1], $dp[$i-2] + $nums[$i]);
    }
    
    return $dp[$n-1];
}

// 示例用法
$nums = [1, 2, 3, 1];
echo rob($nums); // 输出: 4

Python 代码示例

def rob(nums):
    n = len(nums)
    if n == 0:
        return 0
    if n == 1:
        return nums[0]
    
    dp = [0] * n
    dp[0] = nums[0]
    dp[1] = max(nums[0], nums[1])
    
    for i in range(2, n):
        dp[i] = max(dp[i-1], dp[i-2] + nums[i])
    
    return dp[-1]

# 示例用法
nums = [1, 2, 3, 1]
print(rob(nums))  # 输出: 4

JavaScript 代码示例

function rob(nums) {
    const n = nums.length;
    if (n === 0) {
        return 0;
    }
    if (n === 1) {
        return nums[0];
    }
    
    const dp = new Array(n).fill(0);
    dp[0] = nums[0];
    dp[1] = Math.max(nums[0], nums[1]);
    
    for (let i = 2; i < n; i++) {
        dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i]);
    }
    
    return dp[n-1];
}

// 示例用法
const nums = [1, 2, 3, 1];
console.log(rob(nums)); // 输出: 4

在以上代码中,我们使用了动态规划的思想,通过定义一个dp数组来记录到当前房屋为止能偷到的最大金额。由于不能偷相邻的房屋,因此对于每间房屋,我们需要考虑偷当前房屋或不偷当前房屋两种情况,并选择其中较大的金额。通过这种方式,我们最终可以得到偷窃到的最高金额。

推荐面试题