跳至主要內容

198, 打家劫舍

Mike大约 2 分钟dynamic programmingmediumarraydynamic programming

一、题目描述

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

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

示例 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 <= nums.length <= 100
  • 0 <= nums[i] <= 400

相关主题

  • 数组
  • 动态规划

二、题解

方法 1: 动态规划

pub fn rob(nums: Vec<i32>) -> i32 {
    //Self::dp(nums)

    Self::optimize_dp(nums)
}

fn dp(nums: Vec<i32>) -> i32 {
    let len = nums.len();
    match len {
        0 => 0,
        1 => nums[0],
        _ => {
            let mut dp = vec![0; len];
            (dp[0], dp[1]) = (nums[0], max(nums[0], nums[1]));

            for i in 2..len {
                dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
            }

            dp[len - 1]
        }
    }
}

fn optimize_dp(nums: Vec<i32>) -> i32 {
    let len = nums.len();
    match len {
        0 => 0,
        1 => nums[0],
        _ => {
            let (mut first, mut second) = (nums[0], max(nums[0], nums[1]));

            for i in 2..len {
                (first, second) = (second, max(first + nums[i], second));
            }

            second
        }
    }
}