您的位置:首页 > 教育 > 培训 > 【每日刷题】Day115

【每日刷题】Day115

2024/10/5 23:18:34 来源:https://blog.csdn.net/2301_78022459/article/details/142055129  浏览:    关键词:【每日刷题】Day115

【每日刷题】Day115

🥕个人主页:开敲🍉

🔥所属专栏:每日刷题🍍

🌼文章目录🌼

1. LCR 089. 打家劫舍 - 力扣(LeetCode)

2. LCR 090. 打家劫舍 II - 力扣(LeetCode)

3. 740. 删除并获得点数 - 力扣(LeetCode)

1. LCR 089. 打家劫舍 - 力扣(LeetCode)

//思路:多状态动态规划。

class Solution {

public:

    int rob(vector<int>& nums)

    {

        int size = nums.size();

        if(!size) return 0;

        vector<int> f(size);

        auto g = f;

//因为0位置前没有任何数字,同时0位置又是选择偷窃,因此f[0] = nums[0]完成初始化

//而g[0],由于不选择偷窃,而前面也没有数字,因此g[0] = 0

        f[0] = nums[0];

        for(int i = 1;i<size;i++)

        {

//套用方程

            f[i] = g[i-1]+nums[i];

            g[i] = max(f[i-1],g[i-1]);

        }

//最后返回最后一个位置选择偷窃还是不偷窃之间中的最大值

        return max(f[size-1],g[size-1]);

    }

};

2. LCR 090. 打家劫舍 II - 力扣(LeetCode)

//思路:多状态动态规划。

//与打家劫舍Ⅰ的思路基本一致,区别在于,这里的房屋首尾是相连的,这会影响到第一个房子和最后一个房子。

//如果你抢了第一个房子,那么就不能够抢最后一个房子。但是环形也仅仅是影响第一个和最后一个,这中间的房子我们还可以按照打家劫舍Ⅰ的思路来做。分为以下两种情况:

① 如果我们抢了第一个房子,那么我们就不能抢第二个(1)和最后一个(n-1)房子,因此我们需要对 2~n-2 的区间做打家劫舍Ⅰ,让最后的结果加上 第一个房子

② 如果我们不选择抢第一个房子,那么我们从 1~n-1 做打家劫舍Ⅰ

最后返回两种情况下的较大值。

class Solution {

public:

    int rob(vector<int>& nums)

    {

        int size = nums.size();

        if(!size) return 0;

        if(size==1) return nums[0];

        if(size==2) return max(nums[0],nums[1]);

//f1为抢第一个房子的情况

        vector<int> f1(size);

//f2为不抢第一个房子的情况

        vector<int> f2(size);

//g1、g2对应f1、f2

        auto g1 = f1;

        auto g2 = f2;

        f1[2] = nums[2];

        f2[1] = nums[1];

//① 在2~n-2区间的房子做打家劫舍Ⅰ

        for(int i = 3;i<size-1;i++)

        {

            f1[i] = g1[i-1]+nums[i];

            g1[i] = max(f1[i-1],g1[i-1]);

        }

//最后的结果+第一个房子

        int max1 = max(f1[size-2],g1[size-2])+nums[0];

//② 在1~n-1区间的房子做打家劫舍Ⅰ

        for(int i = 2;i<size;i++)

        {

            f2[i] = g2[i-1]+nums[i];

            g2[i] = max(f2[i-1],g2[i-1]);

        }

        int max2 = max(f2[size-1],g2[size-1]);

//返回两种情况的较大值

        return max1>max2?max1:max2;

    }

};

3. 740. 删除并获得点数 - 力扣(LeetCode)

//思路:多状态动态规划。

//本题的思路其实和打家劫舍Ⅰ一模一样,只不过我们要将原数组处理一下:

class Solution {

public:

    int deleteAndEarn(vector<int>& nums)

    {

        vector<int> hash(10001);//哈希数组

        int size = nums.size(),max1 = 0;//max1代表后续对hash数组做 "打家劫舍" 的终点

        for(auto x:nums)

        {

            hash[x]+=x;//将原数组中每个数字的和映射进哈希数组中

            max1 = max1>x?max1:x;//终点就是原数组中的最大值

        }

//对hash做打家劫舍

        vector<int> f(max1+1);

        auto g = f;

        for(int i = 1;i<max1+1;i++)

        {

            f[i] = g[i-1]+hash[i];

            g[i] = max(f[i-1],g[i-1]);

        }

        return max(f[max1],g[max1]);

    }

};

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com