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);
        }
    };
  • 相关阅读:
    Handler
    declare-styleable的使用
    Android APK反编译就这么简单 详解(附图)
    webview与js交互
    Android 开源框架ActionBarSherlock 和 ViewPager 仿网易新闻客户端
    eclipse中的.project 和 .classpath文件的具体作用
    android:关于主工程和library project
    block,inline和inline-block概念和区别
    容易被忽略CSS特性
    CSS里常见的块级元素和行内元素
  • 原文地址:https://www.cnblogs.com/wdw828/p/6870364.html
Copyright © 2011-2022 走看看