zoukankan      html  css  js  c++  java
  • 0213. House Robber II (M)

    House Robber II (M)

    题目

    You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

    Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

    Example 1:

    Input: [2,3,2]
    Output: 3
    Explanation: You cannot rob house 1 (money = 2) and then rob house 3 (money = 2),
                 because they are adjacent houses.
    

    Example 2:

    Input: [1,2,3,1]
    Output: 4
    Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
                 Total amount you can rob = 1 + 3 = 4.
    

    题意

    给定一个首尾相连的循环数组,从中选择一组数,使它们的和最大,但不能选择相邻位置的两个数。

    思路

    与 198. House Robber 相比,多了一个数组循环的条件,限制不能同时选择第一个和最后一个数。实质上和 198 解法一样,只不过需要进行一些修改:排除最后一个数,在前n-1个数中找到最大和sum1;排除第一个数,在后n-1个数中找到最大和sum2。比较sum1和sum2,取较大值即为答案。下为分析:

    A、C分别为首尾数字,B为中间子数组。

    1. 在AB中找到最大和sum1,如果该和包含了A,那么C一定不能选,且再次循环时还是从A开始;如果不包含A,最大和等价于B中的最大和。
    2. 在BC中找到最大和sum2,如果该和包含了C,那么A一定不能选,且再次循环时还是从B开始;如果不包含C,最大和等价于B中的最大和。
    3. max(sum1, sum2)即为答案

    代码实现

    Java

    class Solution {
        public int rob(int[] nums) {
            if (nums.length == 0) return 0;
            if (nums.length == 1) return nums[0];
          
            return Math.max(rob(nums, 0, nums.length - 2), rob(nums, 1, nums.length - 1));
        }
    
        private int rob(int[] nums, int left, int right) {
            if (left == right) return nums[left];
    
            int[] dp = new int[right - left + 1];
            dp[0] = nums[left];
            dp[1] = Math.max(nums[left], nums[left + 1]);
    
            for (int i = left + 2; i <= right; i++) {
                dp[i - left] = Math.max(nums[i] + dp[i - left - 2], dp[i - left - 1]);
            }
    
            return dp[right - left];
        }
    }
    
  • 相关阅读:
    CLR via C#(04) 本是同根生
    CLR via C#(01).NET平台下代码是怎么跑起来的
    CLR via C#(02)基元类型、引用类型、值类型
    Mysql定期自动备份
    Extjs4 图片上传 预览
    inno setup打包应用程序
    bat批处理学习
    localhost/127.0.0.1/本机IP的区别以及端口号
    VirtualBox虚拟机上安装windows7系统
    Linux系统中Oracle11g数据库的安装与验证
  • 原文地址:https://www.cnblogs.com/mapoos/p/13150140.html
Copyright © 2011-2022 走看看