面试算法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];
    }

}
相关推荐
杨凯凡几秒前
【014】基本类型与包装类:缓存、相等性、NPE
java·数据结构·缓存
故事和你911 分钟前
洛谷-算法1-7-搜索3
数据结构·c++·算法·leetcode·动态规划
网域小星球14 分钟前
C++ 从 0 入门(四)|继承、多态、this 指针、深浅拷贝(C++ 面试终极收官)
开发语言·c++·面试·多态·继承·this指针·深浅拷贝
chipsense18 分钟前
霍尔电流传感器选型方法论再升级:从800V平台到TMR竞争的全场景决策树
算法·决策树·机器学习·闭环霍尔·tmr传感
emmjng36930 分钟前
使用飞算JavaAI实现在线图书借阅平台
java
CoderYanger33 分钟前
14届蓝桥杯省赛Java A 组Q1~Q3
java·开发语言·线性代数·算法·职场和发展·蓝桥杯
钮钴禄·爱因斯晨34 分钟前
他到底喜欢我吗?赛博塔罗Java+前端实现,一键解答!
java·开发语言·前端·javascript·css·html
词元Max35 分钟前
Java 转 AI Agent 开发学习路线(2026年3月最新版)
java·人工智能·学习
亚历克斯神36 分钟前
Java 云原生开发最佳实践:构建现代化应用
java·spring·微服务
布说在见36 分钟前
企业级 Java 登录注册系统构建指南(附核心代码与配置)
java·开发语言