zoukankan      html  css  js  c++  java
  • [leetcode] 213. House Robber II

    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.


    这题跟“ House Robber I”类似,只是房子练成了一个圈,即第一间房和最后一间房是相邻的,不能同时偷。因此,现在第一间和最后一间就只能二选一,或者两者都不选。
    所以可以将其分别删掉第一间房和最后一间房,然后通过“House Robber I”分别算出两种情况的最大值,之后选择两值中大值即可。
    此时需要思考的是,去掉第一个元素和最后一个元素,再分别用"House Robber I"求出分别的最大值得到的答案,是否能涵盖所有的答案。
    分析如下:
      最优答案必然是X----------√ 
             √----------X
             X----------X
      之中的一种,而不选第一个的最大值的答案为X----------√或X----------X中的最大值
             不选最后一个个的最大值的答案为√----------X或X----------X的最大值
      因此是涵盖了所有的答案。
    public class Solution {
    	public int rob(int[] nums) {
    		if (nums == null || nums.length == 0) {
    			return 0;
    		}
    		if (nums.length == 1) {
    			return nums[0];
    		}
    		int[] removeFirst = new int[nums.length - 1];
    		int[] removeLast = new int[nums.length - 1];
    		for (int i = 1; i < nums.length; i++) {
    			removeFirst[i - 1] = nums[i];
    		}
    		for (int i = 0; i < nums.length - 1; i++) {
    			removeLast[i] = nums[i];
    		}
    		return Math.max(rob1(removeFirst), rob1(removeLast));
    	}
    	/**
    	 * HouseRobberI
    	 * @param nums
    	 * @return
    	 */
    	public int rob1(int[] nums) {
    		// 共有n家
    		int n = nums.length;
    		if (n == 0) {
    			return 0;
    		}
    		// res[i]表示到第i家止,可以劫到最多的钱
    		int[] res = new int[n + 1];
    		res[0] = 0;
    		res[1] = nums[0];
    
    		for (int i = 2; i < n + 1; i++) {
    			// 劫到第i家能劫得最多的钱,
    			// 1.劫第i家,则说明没劫第i-1家,则此时最多为劫到第i-2家的最多前+第i家的前 = res[i-2] + nums[i-1]
    			// 2.不劫第i家,则劫得最多的钱为劫到第i-1家得到的最多前 res[i-1]
    			res[i] = Math.max(res[i - 2] + nums[i - 1], res[i - 1]);
    		}
    
    		return res[n];
    	}
    }
    

      



  • 相关阅读:
    O(1)时间复杂度实现入栈、出栈、获得栈中最小元素、获得栈中最大元素(转)
    北京网选赛第二题(最大仰望角度)
    最小圆覆盖(随机增量法&模拟退火法)
    模拟退火算法A Star not a Tree?(poj2420)
    模拟退火算法(run away poj1379)
    模拟退火算法(西安网选赛hdu5017)
    最小费用流判负环消圈算法(poj2175)
    中国邮递员问题(一)
    破坏行动问题
    进化树问题
  • 原文地址:https://www.cnblogs.com/zebinlin/p/9803958.html
Copyright © 2011-2022 走看看