LeetCode刷题--- 删除并获得点数

发布时间:2024年01月14日

个人主页:元清加油_【C++】,【C语言】,【数据结构与算法】-CSDN博客

个人专栏

力扣递归算法题

?http://t.csdnimg.cn/yUl2I

【C++】? ??

??????http://t.csdnimg.cn/6AbpV

数据结构与算法

????http://t.csdnimg.cn/hKh2l


前言:这个专栏主要讲述动态规划算法,所以下面题目主要也是这些算法做的 ?

我讲述题目会把讲解部分分为3个部分:
1、题目解析

2、算法原理思路讲解

3、代码实现


删除并获得点数

题目链接:删除并获得点数

题目

给你一个整数数组?nums?,你可以对它进行一些操作。

每次操作中,选择任意一个?nums[i]?,删除它并获得?nums[i]?的点数。之后,你必须删除?所有?等于?nums[i] - 1?和?nums[i] + 1?的元素。

开始你拥有?0?个点数。返回你能通过这些操作获得的最大点数。

示例 1:

输入:nums = [3,4,2]
输出:6
解释:
删除 4 获得 4 个点数,因此 3 也被删除。
之后,删除 2 获得 2 个点数。总共获得 6 个点数。

示例?2:

输入:nums = [2,2,3,3,3,4]
输出:9
解释:
删除 3 获得 3 个点数,接着要删除两个 2 和 4 。
之后,再次删除 3 获得 3 个点数,再次删除 3 获得 3 个点数。
总共获得 9 个点数。

提示:

  • 1 <= nums.length <= 2 * 104
  • 1 <= nums[i] <= 104

解法

算法原理讲解

我们这题使用动态规划,我们做这类题目可以分为以下五个步骤

  1. 状态显示
  2. 状态转移方程
  3. 初始化(防止填表时不越界)
  4. 填表顺序
  5. 返回值

这道题依旧是「打家劫舍I」问题的变型。 我们注意到题?描述,选择 x 数字的时候, x - 1 x + 1 是不能被选择的。像不像「打家 劫舍」问题中,选择 i 位置的?额之后,就不能选择 i - 1 位置以及 i + 1 位置的?额。因此,我们可以创建?个??为 10001 (根据题?的数据范围)的 hash 数组,将 nums 组中每?个元素 x ,累加到 hash 数组下标为 x 的位置处,然后在 hash 数组上来?次「打家劫舍」即可。

状态显示
dp1[i]表示:删除到?i 位置,不删?nums[i],此时最大的数。

dp2[i]表示:删除到 i 位置,不删?nums[i],此时最大的数。

状态转移方程
dp1[i] = dp2[i-1] + nums[i]

dp2[i] = max(dp1[i-1], dp2[i-1])

初始化(防止填表时不越界)
dp1[left] = nums[left];

填表顺序
根据「状态转移?程」得「从左往右,两个表?起填」。

返回值
max(dp1[N-1], dp2[N-1])


代码实现
?

?

class Solution {
public:
    int deleteAndEarn(vector<int>& nums) 
    {
        const int N = 10001;
        int arr[N] = { 0 };
        for(auto x : nums) 
        {
            arr[x] += x;
        }
        
        // 创建 dp 表
        vector<int> f(N);
        auto g = f;
        // 填表
        for(int i = 1; i < N; i++)
        {
            f[i] = g[i - 1] + arr[i];
            g[i] = max(f[i - 1], g[i - 1]);
        }
        // 返回结果
        return max(f[N - 1], g[N - 1]);
    }
};

文章来源:https://blog.csdn.net/weixin_74268082/article/details/135579839
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。