Shawngbk / Leecode

Questions of Leecode
0 stars 0 forks source link

213. House Robber II #123

Open Shawngbk opened 7 years ago

Shawngbk commented 7 years ago

Now the question is how to rob a circular row of houses. It is a bit complicated to solve like the simpler question. It is because in the simpler question whether to rob num[lo] is entirely our choice. But, it is now constrained by whether num[hi] is robbed.

However, since we already have a nice solution to the simpler problem. We do not want to throw it away. Then, it becomes how can we reduce this problem to the simpler one. Actually, extending from the logic that if house i is not robbed, then you are free to choose whether to rob house i + 1, you can break the circle by assuming a house is not robbed.

For example, 1 -> 2 -> 3 -> 1 becomes 2 -> 3 if 1 is not robbed.

Since every house is either robbed or not robbed and at least half of the houses are not robbed, the solution is simply the larger of two cases with consecutive houses, i.e. house i not robbed, break the circle, solve it, or house i + 1 not robbed. Hence, the following solution. I chose i = n and i + 1 = 0 for simpler coding. But, you can choose whichever two consecutive ones. House Robber I的升级版. 因为第一个element 和最后一个element不能同时出现. 则分两次call House Robber I. case 1: 不包括最后一个element. case 2: 不包括第一个element. 两者的最大值即为全局最大值

public class Solution { public int rob(int[] nums) { if(nums==null || nums.length==0) return 0;
if(nums.length==1) return nums[0];
if(nums.length==2) return Math.max(nums[0], nums[1]); return Math.max(helper(nums, 0, nums.length - 2), helper(nums, 1, nums.length - 1)); }

 private int helper(int[] nums, int low, int high) {
    int flag = high - low + 1;
    int[] dp = new int[flag];
    dp[0] = nums[low];
    dp[1] = Math.max(nums[low], nums[low+1]);
    for(int i = 2; i < flag; i++) {
        //因为有可能选第一个或者不选第一个所以nums[i+low],要加标识,0or1
        dp[i] = Math.max(nums[i+low] + dp[i-2], dp[i-1]);
    }
    return dp[flag-1];
}

}

Shawngbk commented 7 years ago

Microsoft