zoukankan      html  css  js  c++  java
  • 213. House Robber II

    Problem statement:

    Note: This is an extension of House Robber.

    After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street.

    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.

    Analysis:

    As mentioned in the description, it is an extension of 198. House Robber. It limits that the first and last houses are also adjacent. 

    Solution one: DP(AC)

    This is my first solution. It shares the same DP formula with 198. House Robber. Since we can choose to rob the first house or not rob the first.

    So, do two times dynamic programming. the differences are the initialized value and return value.

    First DP we suppose to rob the frist house, so r1[i] = nums[0], n1[i] = 0. Only return n1[size - 1]

    Second DP suppose not to rob the first house, r2[i] = 0, n2[i] = 0. Return max(r2[size - 1], n2[size - 1]).

    The final result is max(n1[size - 1], max(r2[size - 1], n2[size - 1])).

    Corner case: just return nums[0] if (nums.size() == 1);

    Time complexity is O(2 * n) ---> O(n).

    class Solution {
    public:
        int rob(vector<int>& nums) {
            if(nums.empty()){
                return 0;
            }
            if(nums.size() == 1){
                return nums[0];
            }
            int size = nums.size();
            // rob the first house
            // only return not_rob
            int r1 = nums[0];
            int n1 = 0;
            for(int i = 1; i < size; i++){
                int r = r1;
                int n = n1;
                r1 = nums[i] + n;
                n1 = max(r, n);
            }
            // do not rob the first house.
            int r2 = 0;
            int n2 = 0;
            for(int i = 1; i < size; i++){
                int r = r2;
                int n = n2;
                r2 = nums[i] + n;
                n2 = max(r, n);
            }
            return max(n1, max(r2, n2));
        }
    };

    Solution two: DP(AC).

    This solution comes from leetcode discussion. In fact, there is no bigger difference with my solution. It smartly chooses the start and end position to decide how to solve the adjacent of first and last elements.

    It looks concise, and the explanations are clear and simple, it follows computer methodology. I like this thinking process. Because not strong, I need more practice.

    Time complexity is O(n).

    class Solution {
    public:
        int rob(vector<int>& nums) {
            if(nums.size() == 1){
                return nums[0];
            }
            return max(max_rob(nums, 0, nums.size() - 2), max_rob(nums, 1, nums.size() - 1));
        }
    private:
        int max_rob(vector<int>& nums, int start, int end){
            int rob = 0, not_rob = 0;
            for(int i = start; i <= end; i++){
                int r = rob;
                int n = not_rob;
                rob = nums[i] + n;
                not_rob = max(r, n);
            }
            return max(rob, not_rob);
        }
    };
  • 相关阅读:
    超级简单:一步一步教你创建一小型的asp.net mvc 应用程序
    asp.net AJAX 验证用户名是否存在 Jquery
    生成缩略图、为图片添加文字水印、图片水印的类
    图Graph
    [转]Implementing a Generic Binary Tree in C#
    .net C#数据结构
    Why HTML5 is worth your time
    跳跃表SkipList
    C# LockFreeStack类
    [转]泛型弱引用
  • 原文地址:https://www.cnblogs.com/wdw828/p/6870364.html
Copyright © 2011-2022 走看看