• 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];
        }
    }
    
  • 相关阅读:
    strdup和strndup函数
    c# 获取客户端IP地址方法
    The 'Microsoft.Jet.OLEDB.4.0' provider is not registered on the local machine.报错解决办法
    C#将Excel数据表导入SQL数据库的两种方法(转)
    Winform 无法监听方向键(向上,向下,向左,向右)
    一个优秀的.net程序员必须要学会的技能 (转)-----参照学习目标
    iTextSharp 使用详解(转)
    mac 快捷键
    mvc 项目运行报错检查web.config
    C语言堆栈入门——堆和栈的区别 -- 转
  • 原文地址:https://www.cnblogs.com/mapoos/p/13150140.html
Copyright © 2020-2023  润新知