• 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);
        }
    };
  • 相关阅读:
    codeforces #586 ABC~D
    codeforces #585 div2 ABCD
    编译原理实验 NFA子集法构造DFA,DFA的识别 c++11实现
    codeforces #599 div2 ABCD
    codeforces #598 div3 ABCDF
    codeforces #587 div3 ABCDE
    codeforces educational round 73 div2 ABCD
    Mud Puddles ( bfs )
    2019牛客多校第十场B.Coffee Chicken(递归)
    2019牛客多校训练第七场A. String(暴力)
  • 原文地址:https://www.cnblogs.com/wdw828/p/6870364.html
Copyright © 2020-2023  润新知