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

      



  • 相关阅读:
    google glog 使用方法
    LIBRARY_PATH和LD_LIBRARY_PATH环境变量的区别
    c++ ‘nullptr’ 在此作用域中尚未声明
    Impala 使用的端口
    忽略“Signal: SIGSEGV (Segmentation fault)”
    查看python脚本的运行pid,让python脚本后台运行
    阿里云主机运行速度慢的解决办法
    在Git.oschina.net中配置TortoiseGit使用sshkey,无需输入账号和密码
    抓取国家的学校编码数据
    CAS统一登录认证好文汇集贴
  • 原文地址:https://www.cnblogs.com/zebinlin/p/9803958.html
Copyright © 2011-2022 走看看