面试算法90:环形房屋偷盗

题目

一条环形街道上有若干房屋。输入一个数组表示该条街道上的房屋内财产的数量。如果这条街道上相邻的两幢房屋被盗就会自动触发报警系统。请计算小偷在这条街道上最多能偷取的财产的数量。例如,街道上5家的财产用数组[2,3,4,5,3]表示,如果小偷到下标为1和3的房屋内盗窃,那么他能偷取到价值为8的财物,这是他在不触发报警系统的情况下能偷取到的最多的财物

分析

由于这个问题和面试题89的区别在于小偷不能同时到标号为0和n-1的两幢房屋内偷东西。如果他考虑去标号为0的房屋,那么他一定不能去标号为n-1的房屋;如果他考虑去标号为n-1的房屋,那么他一定不能去标号为0的房屋。因此,可以将这个问题分解成两个子问题:一个问题是求小偷从标号为0开始到标号为n-2结束的房屋内能偷得的最多财物数量,另一个问题是求小偷从标号为1开始到标号为n-1结束的房屋内能偷得的最多财物数量。小偷从标号为0开始到标号为n-1结束的房屋内能偷得的最多财物数量是这两个子问题的解的最大值。

java 复制代码
public class Test {
    public static void main(String[] args) {
        int[] cost = {2, 3, 4, 5, 3};
        int result = rob(cost);
        System.out.println(result);

    }

    public static int rob(int[] nums) {
        if (nums.length == 0) {
            return 0;
        }

        if (nums.length == 1) {
            return nums[0];
        }

        int result1 = helper(nums, 0, nums.length - 2);
        int result2 = helper(nums, 1, nums.length - 1);
        return Math.max(result1, result2);
    }

    private static int helper(int[] nums, int start, int end) {
        int[] dp = new int[2];
        dp[0] = nums[start];

        if (start < end) {
            dp[1] = Math.max(nums[start], nums[start + 1]);
        }

        for (int i = start + 2; i <= end; i++) {
            int j = i - start;
            dp[j % 2] = Math.max(dp[(j - 1) % 2], dp[(j - 2) % 2] + nums[i]);
        }

        return dp[(end - start) % 2];
    }

}
相关推荐
雪碧聊技术3 小时前
大模型爆火!Java后端如何抓住Agent全栈开发的风口
java·大模型·agent·全栈开发
kyriewen3 小时前
你的代码仓库变成“毛线团”了?Monorepo 用 Turborepo 拆成“乐高积木”
前端·javascript·面试
IT大白鼠3 小时前
AIGC性能的关键瓶颈:算力、数据、算法三者如何互相制约?
算法·aigc
白雪茫茫4 小时前
监督学习、半监督学习、无监督学习算法详解
python·学习·算法·ai
怕浪猫4 小时前
职场真相:稳定是陷阱,35 岁不是终点,而是重新出发的起点
面试
FengyunSky4 小时前
浅析 空间频率响应 SFR 计算
算法
树下水月4 小时前
PHP 一种改良版的雪花算法
算法·php·dreamweaver
逻辑驱动的ken4 小时前
Java高频面试场景题25
java·开发语言·深度学习·面试·职场和发展
一只数据集5 小时前
全尺寸人形机器人灵巧手力觉触觉数据集-2908条ROSbag数据覆盖14大应用场景深度解析
大数据·人工智能·算法·机器人
AI人工智能+电脑小能手5 小时前
【大白话说Java面试题】【Java基础篇】第32题:Java的异常处理机制是什么
java·开发语言·后端·面试