问题描述:

意思就是说:给定一个数组,寻找一种选取方法,使得在保证任何两个相邻元素不同时被选的条件下得到的数值总和最大。

1. 递归

  设nums为数组首地址,numsSize为数组的大小,max[i]表示从第i(0 <= i < numsSize)个元素开始所能得到的最大值。则原问题描述为求max[0]。

  

  其中nums[i]+max[i+2]表示选择第i个元素,因此第i+1个元素不能选择;max[i+1]表示不选择第i个元素,而max[i+1]=max{nums[i+1]+max[i+3], max[i+2]},很明显max[i+2]小于nums[i]+max[i+2],因此:

  

  加上边界控制语句,代码如下:

 int maxMoney ( int *nums, int numsSize, int startIndex) {
     if ( startIndex >= numsSize ) {
         ;
     } ) {
         return *(nums+startIndex);
     }
     );
     ) + maxMoney(nums, numsSize, startIndex+);
     return first>second?first:second;
 }

 int rob(int* nums, int numsSize) {
     ) {
         ;
     }  ) {
         return *nums;
     }  ) {
         )? *nums : *(nums+);
     }
     );
     ) + maxMoney(nums, numsSize, );
     return first>second?first:second;
 }

2. 迭代

  当i=numsSize-1(表示只剩下最后一个元素的时候),最大的只即为nums[i];

  当i=numsSzie-2(剩下最后两个元素的时候,下文其它情况依次类推),最大的情况是nums[i](选择numsSize-2)或nums[i+1](选择numsSize-1);而nums[i+1]已经在i=numsSize-1的时候进行了分析,因此不用再重复;

  当i=numsSize-3时,最大值只可能是

    1. nums[i]+nums[i+2],或者
    2. nums[i+1];

  而nums[i+1](即nums[numsSize-2])已经在第二步计算过,因此只需要记录nums[i]+nums[i+2]的值;

  ……

  下表是一个简单的分析过程,一些不可能出现最大值的情况没有写出来。

  通过上述分析可知,求max[i]时,不选择第i个元素的情况(即max[i+1])已经计算过,因此只需要增加选择第i个元素的情况,那么最终的结果就是这两个值中较大的。

  而对于选择i的情况,第i+1元素由于限制条件将不能选择,因此第i+2个元素可以选可以不选:

    1. 如果选择第i+2个元素,则max[i]=nums[i]+max[i+2];
    2. 如果不选择第i+2个元素,则i+3个元素将必须选择(因为如果不选,则将出现连续3个元素没有选择的情况,这样无论如何都不可能得到一个整体最优的值),则max[i]=nums[i]+max[i+3]

  由于max[i+2]和max[i+3]已经计算出来,因此选择其中一个最大的值作为max[i]的结果。

  这样可以计算出max中所有元素的值,但所有的值都是选择当前假设条件下第一个元素的情况,不选择当前元素的情况即为前一次计算的结果。最终的结果即为max[0]和max[1]中较大的。

 int rob(int* nums, int numsSize) {
      ) {;}
      ) {];}

     , temp2 = ;
      ) {
         temp1 = nums[];
         temp2 = nums[];
         return temp1 > temp2 ? temp1 : temp2;
     } ) {
         temp1 = nums[] + nums[];
         temp2 = nums[];
         return temp1 > temp2 ? temp1 : temp2;
     } else {
         // maxValue[i] 表示选择第i个的最大值
         int *maxValue = (int*)malloc(numsSize * sizeof(int));
         maxValue[numsSize-] = nums[numsSize-];
         maxValue[numsSize-] = nums[numsSize-];
         maxValue[numsSize-] = nums[numsSize-] + nums[numsSize-];
         ; i >= ; i--) {
             temp1 = nums[i] + maxValue[i+];
             temp2 = nums[i] + maxValue[i+];
             maxValue[i] = temp1 > temp2 ? temp1 : temp2;
         }
         // maxValue[0]对应第一个(下标为0)选择的最大值,maxValue[1]对应第1个不选择的最大值
         ] > maxValue[] ? maxValue[] : maxValue[];
     }
 }

LeetCode Day5——House Robber的更多相关文章

  1. Leetcode 337. House Robber III

    337. House Robber III Total Accepted: 18475 Total Submissions: 47725 Difficulty: Medium The thief ha ...

  2. [LeetCode] 213. House Robber II 打家劫舍 II

    Note: This is an extension of House Robber. After robbing those houses on that street, the thief has ...

  3. [LeetCode] 337. House Robber III 打家劫舍 III

    The thief has found himself a new place for his thievery again. There is only one entrance to this a ...

  4. leetcode:House Robber(动态规划dp1)

    You are a professional robber planning to rob houses along a street. Each house has a certain amount ...

  5. [LeetCode] 337. House Robber III 打家劫舍之三

    The thief has found himself a new place for his thievery again. There is only one entrance to this a ...

  6. [LeetCode] 213. House Robber II 打家劫舍之二

    You are a professional robber planning to rob houses along a street. Each house has a certain amount ...

  7. [LeetCode] 198. House Robber 打家劫舍

    You are a professional robber planning to rob houses along a street. Each house has a certain amount ...

  8. 【leetcode】House Robber

    题目简述 You are a professional robber planning to rob houses along a street. Each house has a certain a ...

  9. Leetcode 198 House Robber

    You are a professional robber planning to rob houses along a street. Each house has a certain amount ...

随机推荐

  1. Unity 手指触摸的方向(单手)

    最近写了一个跑酷游戏,总结下里面的知识点:O(∩_∩)O~ using UnityEngine; using System.Collections; public class Demo : MonoB ...

  2. 有关Oracle cvu和cvuqdisk

    有关Oracle cvu和cvuqdisk cvu的下载链接: http://www.oracle.com/technetwork/products/clustering/downloads/cvu- ...

  3. ubuntu系统分区方案

    一.各文件及文件夹的定义 /bin:bin是binary(二进制)的缩写.存放必要的命令 存放增加的用户程序. /bin分区,存放标准系统实用程序./boot:这里存放的是启动LINUX时使用的一些核 ...

  4. Node.js 入门教程和学习资源汇总

    这篇文章与大家分享一批很有用的 Node.js 入门教程和学习资源.Node 是一个服务器端的 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...

  5. PHP学习笔记一

    <html> <head> <title></title> <meta http-equiv="content-type" c ...

  6. Maximum Subarray (JAVA)

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  7. javascirpt的apply和call

    javascirpt的apply和call用法如下: var arr1=new Array("1","2","3");      var a ...

  8. sql 练习(1)

    1.建立实验表 CREATE TABLE STUDENT (SNO ) NOT NULL, SNAME ) NOT NULL, SSEX ) NOT NULL, SBIRTHDAY DATE, CLA ...

  9. linux学习笔记之文件类型,及目录介绍

    引用A:http://www.cnblogs.com/xiaoluo501395377/archive/2013/04/20/3033131.html 引用B:http://www.cnblogs.c ...

  10. listview滚动到底部

    方法一: // msgListView是ListView控件 // adapter是ListView绑定的Adapter,如果不方便直接使用,也可以通过ListView的getAdapter()方法获 ...