后端开发刷题 | 打家劫舍

描述

你是一个经验丰富的小偷,准备偷沿街的一排房间,每个房间都存有一定的现金,为了防止被发现,你不能偷相邻的两家,即,如果偷了第一家,就不能再偷第二家;如果偷了第二家,那么就不能偷第一家和第三家。

给定一个整数数组nums,数组中的元素表示每个房间存有的现金数额,请你计算在不被发现的前提下最多的偷窃金额。

数据范围:数组长度满足 1≤n≤2×105,数组中每个值满足 1≤numi≤5000

示例1

输入:

复制代码
[1,2,3,4]

返回值:

复制代码
6

说明:

复制代码
最优方案是偷第 2,4 个房间   

示例2

输入:

复制代码
[1,3,6]

返回值:

复制代码
7

说明:

复制代码
最优方案是偷第 1,3个房间   

示例3

输入:

复制代码
[2,10,5]

返回值:

复制代码
10

说明:

复制代码
最优方案是偷第 2 个房间  

思路分析:

该题使用动态规划来解决,

具体做法:

  • step 1:用dpi表示长度为i的数组,最多能偷取到多少钱,只要每次转移状态逐渐累加就可以得到整个数组能偷取的钱。
  • step 2:(初始状态) 如果数组长度为1,只有一家人,肯定是把这家人偷了,收益最大,因此dp1=nums0
  • step 3:(状态转移) 每次对于一个人家,我们选择偷他或者不偷他,如果我们选择偷那么前一家必定不能偷,因此累加的上上级的最多收益,同理如果选择不偷他,那我们最多可以累加上一级的收益。因此转移方程为dpi=max(dpi−1,numsi−1+dpi−2)。这里的i在dp中为数组长度,在nums中为下标。

图示:

代码:

java 复制代码
import java.util.*;


public class Solution {
    /**
     * @param nums int整型一维数组 
     * @return int整型
     */
    public int rob (int[] nums) {
        int[] dp=new int[nums.length+1];
        dp[1]=nums[0];
        for(int i=2;i<=nums.length;i++){
            dp[i]=Math.max(dp[i-1],nums[i-1]+dp[i-2]);
        }
        return dp[nums.length];
    }
}
相关推荐
s_w.h5 小时前
【 刷题 】双指针
算法
啥都想学点的研究生5 小时前
一篇文章讲清楚:K-Means聚类算法
算法·kmeans·聚类
泡海椒5 小时前
低代码规则开发:JQuick-Java声明式配置驱动开发落地教程
java·低代码·rxjava
白狐_7986 小时前
408 数据结构|KMP做题方法:next、nextval和高频易错点
数据结构·算法
月华路6 小时前
《模型不玄学》第20章 两种评估视角
人工智能·算法·机器学习
变与不变8066 小时前
引用类型、内存原理与对象
开发语言·前端·javascript
wuyk5556 小时前
从零吃透 MQTT 通信|第 5 章 MQTT 心跳保活机制深度优化,断线检测与智能自动重连
c语言·开发语言·stm32·学习
weixin_440730506 小时前
socket解决多次输入问题-大数据接收问题-模块动态导入
java·开发语言·servlet
用户3126874877206 小时前
ReentrantLock 和 synchronized 到底选哪个?源码级对比与选型
java
计算机毕设定制辅导-无忧学长6 小时前
基于Spring Boot的玄幻小说个性化推荐平台设计与实现
java·vue.js·spring boot·后端·mysql·推荐算法