[LeetCode] House Robber

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

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.

分析一:DP问题。如果偷盗第i家,那么偷盗当前第i家获得的最大收益是偷盗[1~i-2]中的某一家获得的最大收益再加上当前这一家的金钱数目。不能偷盗相邻的,也就不能偷盗第i-1家。递推公式为profit[i] = max{profit[1], profit[2], ..., profit[i-2]},没有i-1因为不能偷盗相邻家。

    时间复杂度O(n2),空间复杂度O(n)

class Solution {
public:
    int rob(vector<int>& nums) {
        vector<int> profit(nums.size());

        int max_profit = 0;
        for (int i = 0; i < nums.size(); i++) {
            profit[i] = nums[i];
            int temp_max_profit = 0;
            for (int j = i - 2; j >= 0; j--) {
                if (profit[j] > temp_max_profit) temp_max_profit = profit[j];
            }
            profit[i] = temp_max_profit + nums[i];

            if (profit[i] > max_profit)
                max_profit = profit[i];
        }

        return max_profit;

    }
};

分析二:

  我们从上述分析可以看到,如果记录[1~i-2]的最大值的话,就能避免每次偷i家的时候的循环查找操作。我们将这个这个最大值记作pen_profit。每次偷完一家都要更新pen_profit后续使用。  

  时间复杂度O(n),空间复杂度O(n)

class Solution {
public:
    int rob(vector<int>& nums) {
        vector<int> profit(nums.size());

        int max_profit = 0;
        int pen_profit = 0;

        for (int i = 0; i < nums.size(); i++) {
            profit[i] = pre_profit + nums[i];
            if (i - 1 >= 0 && profit[i-1] > pen_profit) pen_profit = profit[i-1];

            if (profit[i] > max_profit)
                max_profit = profit[i];
        }

        return max_profit;

    }
};

分析三:我们已经把时间复杂度降下来了。能不能再把O(N)的空间复杂度降下来呢。目前profit数组(vector)的作用有两个:更新pen_profit和用来与max_profit作比较。我们看到更新pen_profit一直使用的是profit[i-1],所以如果我们能一直维持一个变量用来存储最新的profit[i-1]的话,我们就可以放弃数组了。这里我们用pre_profit表示profit[i-1]。profit数组与max_profit作比较的操作每次使用的是profit[i]也就是每次循环计算出来新鲜的profit值。那么就用curr_profit保存这个刚刚计算出来的profit。这样在这一步就不用profit的vector了。

  时间复杂度O(n),空间复杂度O(1)

class Solution {
public:
    int rob(vector<int>& nums) {

        int max_profit = 0;
        int pen_profit = 0;
        int pre_profit = 0;

        for (int i = 0; i < nums.size(); i++) {
            int curr_profit = pen_profit + nums[i];
            if (i - 1 >= 0 && pre_profit > pen_profit) pen_profit = pre_profit;

            if (curr_profit > max_profit)
                max_profit = curr_profit;
            pre_profit = curr_profit; //更新pre_profit
        }

        return max_profit;

    }
};
时间: 2024-12-21 03:26:42

[LeetCode] House Robber的相关文章

LeetCode House Robber III

原题链接在这里:https://leetcode.com/problems/house-robber-iii/ 题目: The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the "root." Besides the root, each house has one and only one parent hous

[leetcode] House Robber python 解决方案

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will autom

LeetCode -- House Robber II

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. 

LeetCode——House Robber

Description: You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and

LeetCode—House Robber 寻找数组不相邻组合最大值DP

https://leetcode.com/problems/house-robber/ 题目设计了一个抢劫犯的情景,其实就是求数组中不相邻数据进行组合得到的最大值 举一个例子 假设数据: 8 3 6 15 4 9 7 10 那么首先可能选取 8 , 3 每一个数字的选取都是根据他的前两个数字,前三个数字得到的最大值进行选择,等到6的时候考虑前面只能和8组合  8,3,14 到数字15,那么就可以考虑在8,3中进行组合  8,3,14,23,4,9,7,10 接下来的步骤: 8,3,14,23,1

[LeetCode] House Robber II 打家劫舍之二

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.

[LeetCode] House Robber 打家劫舍

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will autom

LeetCode House Robber 家庭劫犯(dp)

题意:有一个整数序列,从中挑出一些数字,使得总和是最大,前提是,相邻的两个数字中只能挑其一.比如1 2 3 就只能挑2或者1和3. 思路:很直观的题,dp思想.降低规模,从小规模开始考虑.如果只有两个数字,那么结果很明显就能知道是其中之大者.假如已经知道了第 i 个之前的决策,那么第i+2个之前的决策也就知道了.前两个数字已经由人工得知,设为dp[0]和dp[1],那么dp[2]=max(dp[0]+nums[2], dp[1]).状态转移方程dp[i]=max(dp[i-1], dp[i-2]

Solution to LeetCode Problem Set

Here is my collection of solutions to leetcode problems. LeetCode - Course Schedule LeetCode - Reverse Linked List LeetCode - Isomorphic Strings LeetCode - Count Primes LeetCode - Remove Linked List Elements LeetCode - Happy Number LeetCode - Bitwise