LeetCode 198打家劫舍 213打家劫舍-ii 337打家劫舍-iii 121买卖股票的最佳时机 122买卖股票的最佳时机-ii | 代码随想录25期训练营day48/49

动态规划算法7

LeetCode 198 打家劫舍 2023.12.12

int rob(vector<int>& nums) {
    
    
    //1确定dp数组及其下标含义,dp[i]表示遍历(0,i)nums子数组的最大金额
    vector<int> dp(nums.size());
    //3初始化,dp[0]=第一间房屋的金额;dp[1]=第一间与第二间的最大金额
    dp[0] = nums[0];
    //需要判断nums数组大小,当size>1时才能初始化dp[1]
    if(nums.size() >= 2)
        dp[1] = max(nums[0], nums[1]);
    //2确定递推公式,dp[i]=max(取当前房屋i金额+第i-2房间前的最大金额,第i-1间房间前的最大金额)
    for (int i = 2; i < nums.size(); i++)
    {
    
    
        dp[i] = max(nums[i]+dp[i-2], dp[i-1]);
    }
    return dp[nums.size()-1];
}

LeetCode 213 打家劫舍-ii 2023.12.12

class Solution {
    
    
public:
    //求某一非循环数组的最大打家劫舍价值
    int robrange(vector<int>& nums, int begin, int end)
    {
    
    
        //1确定dp数组及其下标含义,dp[i]表示遍历(begin,i)nums子数组的最大金额
        vector<int> dp(nums.size(), 0);
        //3初始化,dp[begin]=第begin间房屋的金额;dp[begin+1]=相邻这两间的最大金额
        dp[begin] = nums[begin];
        dp[begin+1] = max(nums[begin], nums[begin+1]);
        //2确定递推公式,dp[i]=max(取当前房屋i金额+第i-2房间前的最大金额,第i-1间房间前的最大金额)
        for(int i = begin+2; i <= end; i++)
            dp[i] = max(nums[i] + dp[i-2], dp[i-1]);
        return dp[end];
    }
    int rob(vector<int>& nums) {
    
    
        //分类讨论
        //1、只有一间房屋,那么返回该间房的金额
        if(nums.size() == 1)
            return nums[0];
        //2、有两间房屋,那么返回这两间房的较大金额  
        if(nums.size() == 2)
            return max(nums[0], nums[1]);
        //3、有多间房,那么选择动态规划的最大值
        //环形数组的最后解范围有三中,1、[0, nums.size()-2];2、[1, nums.size()-1];3、[1, nums.size()-2]
        //第二种情况包括第三种情况,那么选取第一、二种情况的较大值作为答案
        else
            return max(robrange(nums, 0, nums.size()-2), robrange(nums, 1, nums.size()-1));
    }
};

LeetCode 337 打家劫舍-iii 2023.12.12

class Solution {
    
    
public:
    //暴力求解,需配合查找表使用,否则超时
    //unordered_map<TreeNode*, int> unmap;
    // int rob(TreeNode* root) {
    
    
    //     if(root == NULL)
    //         return 0;
    //     if(root->left == NULL && root->right == NULL)
    //         return root->val;
    //     if(unmap[root])
    //         return unmap[root];
    //     //1取当前root,那么值为当前root值+其4个孙子的值
    //     int val1 = root->val;
    //     if(root->left)
    //         val1 += rob(root->left->left) + rob(root->left->right);
    //     if(root->right)
    //         val1 += rob(root->right->left) + rob(root->right->right);
    //     //2不取当前root,那么值为其2个儿子的值的和
    //     int val2 = rob(root->left) + rob(root->right);
    //     //将当前root的最大价值存入查找表,用于下次计算时查找,提高效率
    //     unmap[root] = max(val1, val2);
    //     //返回当前root的最大价值
    //     return unmap[root];
    // }

    //递归+动态规划方法
    vector<int> robTree(TreeNode* root)
    {
    
    
        //递归退出条件
        if(root == NULL)
            return {
    
    0, 0};
        //创建要返回的当前数组,cur[0]表示不取当前root值时的价值;cur[1]表示取当前root值时的价值
        vector<int> cur(2, 0);
        vector<int> left = robTree(root->left);
        vector<int> right = robTree(root->right);
        //不取当前root值
        cur[0] = max(left[0], left[1]) + max(right[0], right[1]);
        //取当前root值
        cur[1] = root->val + left[0] + right[0];
        return cur;
    }
    int rob(TreeNode* root) {
    
    
        vector<int> result = robTree(root);
        return max(result[0], result[1]);
    }
};

LeetCode 121 买卖股票的最佳时机 2023.12.12

int maxProfit(vector<int>& prices) {
    
    
    //暴力求解
    // int result = 0;
    //两次循环求数组中最大元素差
    // for (int i = 0; i < prices.size(); i++)
    // {
    
    
    //     for(int j = i; j < prices.size(); j++)
    //         result = max(result, prices[j]-prices[i]);
    // }
    // return result;

    //贪心算法
    //更新最小值与最大收益
    // int minValue = prices[0];
    // int result = 0;
    // for (int i = 0; i < prices.size(); i++)
    // {
    
    
    //     minValue = min(minValue, prices[i]);
    //     result = max(result, prices[i]-minValue);
    // }
    // return result;

    //动态规划
    //更新最小值与最大收益
    // vector<int> dp(prices.size(), 0);
    // int min = prices[0];
    // for(int i = 1; i < prices.size(); i++)
    // {
    
    
    //     if(min > prices[i])
    //         min = prices[i];
    //     dp[i] = max(prices[i]- min, dp[i-1]);
    // }
    // return dp[prices.size()-1];

    //1创建dp二维数组
    //dp[i][0]表示遍历到第i天时持有股票的当前收入;dp[i][1]表示遍历到第i天时未持有股票的当前收入
    vector<vector<int>> dp(prices.size(), vector<int>(2,0));
    //3初始化,第一天持有股票的收入为-prices[0],其他值为0
    dp[0][0] = -prices[0];
    //2确定递推公式,4确定遍历顺序
    for (int i = 1; i < prices.size(); i++)
    {
    
    
        //第i天持有股票的收入=max(股票不卖(上一天持有股票的收入),之前买的不算,买当天的股票的收入)
        dp[i][0] = max(dp[i-1][0], -prices[i]);
        //第i天未持有股票的收入=max(上一天未持有股票的收入,今天卖股票的收入)
        dp[i][1] = max(dp[i-1][1], dp[i-1][0]+prices[i]);
    }
    return dp[prices.size()-1][1];
}

LeetCode 122 买卖股票的最佳时机-ii 2023.12.12

int maxProfit(vector<int>& prices) {
    
    
    //贪心算法
    // //result存储收益
    // int result = 0;
    // //cur存储当前手中股票价格,因为股票价格有0,所以初始化手中没股票时cur=-1
    // int cur = -1;
    // //遍历
    // for (int i = 0; i < prices.size(); i++)
    // {
    
    
    //     //当手中没股票且当日价格小于下一日价格时买入并遍历到下一天
    //     if(cur == -1 && i+1 < prices.size() && prices[i] < prices[i+1])
    //     {
    
    
    //         cur = prices[i];
    //         continue;
    //     }
    //     //当手中有股票,且当日股价大于买入价,而且明天就没有价格了或者明天价格比今天低的时候卖出,更新收益
    //     if(cur != -1 && prices[i] > cur && (i == prices.size()-1 || (i+1 < prices.size() && prices[i] > prices[i+1])))
    //     {
    
    
    //         result += (prices[i] - cur);
    //         cur = -1;
    //     }    
    // }
    // return result;

    //动态规划算法
    //1确定dp二维数组
    //dp[i][0]表示遍历到第i天时持有股票的当前收入;dp[i][1]表示遍历到第i天时未持有股票的当前收入
    vector<vector<int>> dp(prices.size(), vector<int>(2, 0));
    //3初始化,第一天持有股票的收入为-prices[0],其他值为0
    dp[0][0] = -prices[0];
    //2确定递推公式,4确定遍历顺序
    for (int i = 1; i < prices.size(); i++)
    {
    
    
        //第i天持有股票的收入=max(股票不卖(上一天持有股票的收入),昨天没持有买完今天的股票的收入)
        dp[i][0] = max(dp[i-1][0], dp[i-1][1]-prices[i]);
        //第i天未持有股票的收入=max(上一天未持有股票的收入,今天卖股票的收入)
        dp[i][1] = max(dp[i-1][1], dp[i-1][0]+prices[i]);
    }
    return dp[prices.size()-1][1];
}

猜你喜欢

转载自blog.csdn.net/weixin_66706867/article/details/134956948
今日推荐