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];
    	}
    }
    

      



  • 相关阅读:
    Mysql查询正在运行的事务
    linux SVN添加新用户
    linux下安装php扩展amqp
    解决apache启动错误:Could not reliably determine the server's fully qualified domain name
    linux系统安装redis服务器与php redis扩展
    navicat导出数据库字典
    centos安装GD库失败
    Mysql实现主从同步
    计算机的本质
    windows下nginx访问web目录提示403 Forbidden
  • 原文地址:https://www.cnblogs.com/zebinlin/p/9803958.html
Copyright © 2011-2022 走看看