public class Solution { public int Rob(int[] nums) { int i = 0; int e = 0; for (int k = 0; k < nums.Length; k++) { int tmp = i; i = nums[k] + e; e = Math.Max(tmp, e); } return Math.Max(i, e); }}
/*
你是一个专业强盗,并计划沿街去盗窃每一个住户。每个房子都有一定量的现金,阻止你盗窃的唯一阻碍是相邻的两个房子之间有安全系统。一旦这两个房子同时被盗窃,系统就会自动联系警察。给定一系列非负整数代表每个房子的金钱,求出在不惊动警察的情况下能盗窃到的最大值*/上面的程序不是很容易理解,略微进行修改如下:
public class Solution { public int Rob(int[] nums) { if (nums.Length > 0) { int i = nums[0]; int e = 0; for (int k = 1; k < nums.Length; k++) { var tmp = nums[k] + e;//抢当前的房间的累积金额,临时存储 e = Math.Max(i, e); //i:不抢当前房间但是抢前一个房间 //e:不抢当前房间同时不抢前一个房间 //两者大的是新的e:不抢当前房间累积金额 i = tmp;//抢当前房间的累积金额 } return Math.Max(i, e); } else { return 0; } } }
经过一段时间学习,重新做这道题,使用了更加容易理解的写法:
public class Solution { public int Rob(int[] nums) { var len = nums.Length; if (len == 0) { return 0; } else if (len == 1) { return nums[0]; } else if (len == 2) { return Math.Max(nums[0], nums[1]); } //len>=3 //var robmoney = 0;//累计的抢夺的钱 var money = new int[len];//记录截止到当前位置最多的金额 money[0] = nums[0]; money[1] = Math.Max(nums[0], nums[1]); for (int i = 2; i < len; i++) { //如果当前房间-1已经被抢了,那么当前房间不能抢 新的累计金额是之前最大金额 //如果当前房间-1没有被抢,则新的累计金额是 之前最大金额+当前房间金额 money[i] = Math.Max(money[i - 1], money[i - 2] + nums[i]); //robmoney += money[i]; } return money[len-1]; } }
用money数组记录,到当前i位置为止,所抢夺的最大的金额。
决定当前的i位置是否要抢里面的钱,根据i-1房间是否已经抢过来判断。
如果i-1房间被抢,那i位置房间的金额就不可以再抢。如果i-1房间没有被抢,则i位置最大金额就是i-2的最大金额+i房间的金额。
每次记录的是,截止到目前位置,最大的金额数。也就是这两种方案中较大的一种。