• 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);
        }
    };
  • 相关阅读:
    采购申请 POCIRM-001:ORA-01403: 未找到任何数据
    前后端交互技术有哪些
    React实现类似淘宝tab居中切换效果
    CSS通过text-transform实现大写、小写和首字母大写转换
    从浏览器内部运行机制看性能优化
    设置网页浏览器标签小图标
    前后端分离的优缺点
    修改input搜索框默认叉号的样式为自定义图片
    编写优秀CSS代码的8个策略
    css如何设置不可复制?
  • 原文地址:https://www.cnblogs.com/wdw828/p/6870364.html
Copyright © 2020-2023  润新知