zoukankan      html  css  js  c++  java
  • 动态规划——LeetCode213打家劫舍 II

    你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

    给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。

    示例 1:

    输入: [2,3,2]
    输出: 3
    解释: 你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。
    示例 2:

    输入: [1,2,3,1]
    输出: 4
    解释: 你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。
         偷窃到的最高金额 = 1 + 3 = 4 。

    思考:此题和一般递归转化为动态规划的套路略微不同,区别在于第一个和最后一个不能同时取到,因此转换为不取第一个,和不取最后一个两个动态规划,求这两个动态规划的最最大值即可,此问题类似于一步阶梯和两步阶梯上楼的问题,最后一步和倒数第二步都有可能是最优解,因此需要求完dp数组之后再进行一次比较

    Java代码如下:

    class Solution {
        public int rob(int[] nums) {
            if ( nums.length <= 0 ) {
                return 0;
            }
            int n = nums.length;
            if ( n == 1 ) {
                return nums[0];
            }
            int arr1[] = new int[n-1];
            int arr2[] = new int[n-1];
            for( int i = 0 ; i < n-1 ; i++ ) {
                arr1[i] = nums[i];
            }
            for( int i = 1 ; i < n ; i++ ) {
                arr2[i-1] = nums[i];
            }
            return Math.max( helper(arr1) , helper(arr2) );
        }
    
        public int helper( int[] a ) {
            int n = a.length;
            int dp[] = new int[n+1];
            dp[0] = 0;
            dp[1] = a[0];
            for( int i = 2 ; i <= n ; i++ ) {
                dp[i] = Math.max( dp[i-1] , dp[i-2] + a[i-1] );
            }
            return dp[n];
        }
    }
  • 相关阅读:
    mac上python3安装HTMLTestRunner
    双目深度估计传统算法流程及OpenCV的编译注意事项
    深度学习梯度反向传播出现Nan值的原因归类
    1394. Find Lucky Integer in an Array
    1399. Count Largest Group
    1200. Minimum Absolute Difference
    999. Available Captures for Rook
    509. Fibonacci Number
    1160. Find Words That Can Be Formed by Characters
    1122. Relative Sort Array
  • 原文地址:https://www.cnblogs.com/cg-bestwishes/p/11925796.html
Copyright © 2011-2022 走看看