Leetcode——House Robber系列

198. 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家最多可获利,则dp[i] = max(dp[i - 1], dp[i - 2] + nums[i - 1]) 注意:nums是从0开始的

时间复杂度为O(n), 空间复杂度也是O(n);

    int rob(vector& nums) {
        int n = nums.size();
        if(n == 0)
            return 0;
        vector dp(n + 1 , 0);
        dp[1] = nums[0];
        for(int i = 2; i <= n; i ++)
            dp[i] = max(dp[i - 1], dp[i - 2] + nums[i - 1]);
        return dp[n];
    }

 

213. House Robber II

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, 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.

法:由于呈现环形,所以第一家和最后一家只能二选其一,故可以选择只保留第一家和只保留最后一家各求一次取最大值,时间复杂度为O(n), 空间复杂度也是O(n)

    int robCore(vector& nums, int begin, int end) {
        int n = end - begin + 1;
        if(n == 0)
            return 0;
        vector dp(n + 1 , 0);
        dp[1] = nums[begin];
        for(int i = 2; i <= n; i ++)
            dp[i] = max(dp[i - 1], dp[i - 2] + nums[begin + i - 1]);
        return dp[n];
    }
    int rob(vector& nums) {
        if(nums.size() == 0)
            return 0;
        if(nums.size() == 1)
            return nums[0];
        return max(robCore(nums, 0, nums.size() - 2), robCore(nums, 1, nums.size() - 1));
    }

 

337. 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 house. After a tour, the smart thief realized that "all houses in this place forms a binary tree". It will automatically contact the police if two directly-linked houses were broken into on the same night.

Determine the maximum amount of money the thief can rob tonight without alerting the police.

法: 给的例子具有欺骗性,初始想法为层次遍历树,记录每层和,然后按照house robber进行计算,错误样例为:[2,1,3,null,4],输出6,理应为7,注意不一定非得隔层,只要不相连(不是父子关系)即可。

因为当前的计算需要依赖之前的结果,典型的递归回溯,这种方法的递归函数返回一个大小为2的一维数组res,其中res[0]表示不包含当前节点值的最大值,res[1]表示包含当前值的最大值,那么我们在遍历某个节点时,首先对其左右子节点调用递归函数,分别得到包含与不包含左子节点值的最大值,和包含于不包含右子节点值的最大值,那么当前节点的res[0]就是左子节点两种情况的较大值加上右子节点两种情况的较大值,res[1]就是不包含左子节点值的最大值加上不包含右子节点值的最大值,和当前节点值之和,返回即可

    int rob(TreeNode* root) {
        vector res = dfs(root);
        return max(res[0], res[1]);
    }
    vector dfs(TreeNode *root) {
        if (!root) 
            return vector(2, 0);
        vector left = dfs(root->left);
        vector right = dfs(root->right);
        vector res(2, 0);
        res[0] = max(left[0], left[1]) + max(right[0], right[1]);
        res[1] = left[0] + right[0] + root->val;
        return res;
    }

 

你可能感兴趣的:(C++,算法)