392. House Robber I/II

392. House Robber

Tag:

Dynamic Problem

Main Idea:

Rolling array problem. To solve the DP problem, we need to consider the base cases and update function.
In this problem, let   r o b [ i ] \ rob[i] represents the max item value at the position i,   A [ i ] \ A[i] means the item-value at the position i. In this case, the update function would be   r o b [ i ] = m a x ( r o b [ i 1 ] , r o b [ i 2 ] + A [ i ] ) \ rob[i] = max(rob[i-1], rob[i-2]+A[i]) . Therefore, the base case we need to pay attention to are   r o b [ 0 ] , r o b [ 1 ] \ rob[0], rob[1] .

Above is the basic idea of this problem. For the optimization, we can save space cost here, because every time it only need to compare the   r o b [ i 1 ] , r o b [ i 2 ] \ rob[i-1], rob[i-2] .

Tips: When it comes to rolling array problem, all we need to do is write down the code. After it works successfully, MOD EVERY index of the array.

Time/Space Cost:

Time Cost:   O ( n ) \ O(n)
Space Cost:   O ( 1 ) \ O(1)

Code:

class Solution {
public:
    /**
     * @param A: An array of non-negative integers
     * @return: The maximum amount of money you can rob tonight
     */
    long long houseRobber(vector<int> &A) {
        // write your code here
        int len = A.size();
        vector<long long> rob(len, 0);
        
        if(A.empty()){
            return -1;
        }
        if(len == 1){
            return A[0];
        }
        if(len == 2){
            return A[0] > A[1] ? A[0] : A[1];
        }
        
        rob[0] = A[0];
        rob[1] = A[1];
        for(int i = 2; i< len; i++ ){
        	// !!! implement of rolling array
            rob[i%2] = max(rob[(i-1)%2], rob[(i-2)%2]+A[i]);
        }
        
        return rob[(len-1)%2];
        
    }
};

Follow-up Problem1: 534. House Robber II

What if houses are circle, the thief can not steal the both first and last houses?

Main Idea:

Main idea: Based on the first problem, the main idea is similar. What makes it different is that we need to consider the corner case. The case is that whether to chose the first house meanwhile abandon the last house Or vice versa.

In this situation, all we need to do is run the for-loop twice. Let   n \ n be the number of the houses. At the first time, we set the range of house from 0 to n-1. At the second time, we set the range from 1 to n.

Time/Space Cost:

Time Cost:   O ( n ) \ O(n)
Space Cost:   O ( 1 ) \ O(1) (after optimization)

Code:

In this code, I did not implement rolling array to save the space cost. But the main idea is same.

class Solution {
public:
    /**
     * @param nums: An array of non-negative integers.
     * @return: The maximum amount of money you can rob tonight
     */
    int houseRobber2(vector<int> &nums) {
        // write your code here
        int len = nums.size();
        if(len == 0)  return -1;
        if(len == 1)  return nums[0];
        vector<int> rob(len);
        
        int res;
        
        // note from here
        // the first time for-loop, range from 1 to n
        
        rob[0] = 0;
        rob[1] = nums[1];
        for(int i = 2; i < len; i++)
        {
            rob[i] = max(rob[i-1], rob[i-2] + nums[i]);
        }
        res = rob[len-1];

        // the second time for-loop, range from 0 to n-1
        rob[0] = nums[0];
        rob[1] = max(nums[0], nums[1]);
        for(int i = 2; i < len; i++)
        {
            rob[i] = max(rob[i-1], rob[i-2] + nums[i]);
        }
        // index n-1 represents the last second element.
        res = max(res, rob[len-2]);
        
        return res;
        
    }
};

发布了10 篇原创文章 · 获赞 0 · 访问量 104

猜你喜欢

转载自blog.csdn.net/Zahb44856/article/details/103889290