【Leetcode】740- 删除并获得点数

2024-05-01 01:04

本文主要是介绍【Leetcode】740- 删除并获得点数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

问题简述

给你一个整数数组 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 * 10⁴
1 <= nums[i] <= 10⁴

思路分析

对于该问题,选择任意一个nums[i]删除操作中需要频繁查找等于nums[i]-1和nums[i]+1的元素。由于原数组的元素存储是无序的,不便反复查找特定值的元素,因此我们新建一个数组,以数值大小作为下标,每个数值的出现次数为值,这样直接通过下标检索特定值的元素判断其是否存在,就可以省略这些查找的动作。
因此启发了我们从另一个角度分析,如果从数值的角度来考虑是否删除当前元素,则可以将原问题拆分为一个分阶段求解的问题。从数值小的元素开始求解,设第n个阶段的问题为——是否删除数值为n的元素,有2种可选方案:(1)删除n(注意若有多个值为n的数应该全部删除以获取尽量多的点数),那么需要同时删除n-1和n+1,获取点数为 n × \times ×n的个数+阶段n-2获取的点数;(2)n不存在或者不删除n,那么可以直接采用阶段n-1的决策方案,获取点数为 阶段n-1的获取点数
可见,该问题也是一个可以使用动态规划来求解的问题。第n个阶段的问题的解是基于子问题(阶段n-1和阶段n-2)的最优解来推断得到的,具有最优子结构的特性;每个阶段的状态就是当前阶段获取的点数,第n个阶段的问题的决策只与阶段n-1和阶段n-2的状态(即 子问题的最优解)有关,与此之前阶段的状态无关,满足无后效性。该问题的状态转移方程为:dp[n] = max(dp[n-1], n × \times ×c+dp[n-2]),其中c指的是数值为n的元素个数。
具体实现时,为了减少占用空间,可以不用状态数组dp来存储每个阶段的状态,因为阶段n的状态仅与阶段n-1及阶段n-2的状态有关,使用两个变量分别指代前两个状态即可。

代码示例

class Solution:def deleteAndEarn(self, nums: List[int]) -> int:# 创建一个数组记录每个数值的出现次数counts = [0] * (max(nums) + 1)for i in range(len(nums)):counts[nums[i]] += 1# 使用两个变量分别指代当前阶段的前两个阶段的状态ppre, pre = counts[0], max(counts[0], counts[1])for j in range(2, len(counts)): # 状态转移方程ppre, pre = pre, max(pre, ppre + j * counts[j])return pre

复杂度分析

时间复杂度 O ( n + m ) O(n+m) O(n+m)
空间复杂度 O ( m ) O(m) O(m)
其中m为数组nums的最大值,由于需要遍历原数组和新创建数组,时间复杂度取决于两个数组的长度,空间复杂度取决于新创建数组的长度。

这篇关于【Leetcode】740- 删除并获得点数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/950355

相关文章

C#实现获得某个枚举的所有名称

《C#实现获得某个枚举的所有名称》这篇文章主要为大家详细介绍了C#如何实现获得某个枚举的所有名称,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下... C#中获得某个枚举的所有名称using System;using System.Collections.Generic;usi

Oracle数据库使用 listagg去重删除重复数据的方法汇总

《Oracle数据库使用listagg去重删除重复数据的方法汇总》文章介绍了在Oracle数据库中使用LISTAGG和XMLAGG函数进行字符串聚合并去重的方法,包括去重聚合、使用XML解析和CLO... 目录案例表第一种:使用wm_concat() + distinct去重聚合第二种:使用listagg,

Redis过期键删除策略解读

《Redis过期键删除策略解读》Redis通过惰性删除策略和定期删除策略来管理过期键,惰性删除策略在键被访问时检查是否过期并删除,节省CPU开销但可能导致过期键滞留,定期删除策略定期扫描并删除过期键,... 目录1.Redis使用两种不同的策略来删除过期键,分别是惰性删除策略和定期删除策略1.1惰性删除策略

SpringBoot项目删除Bean或者不加载Bean的问题解决

《SpringBoot项目删除Bean或者不加载Bean的问题解决》文章介绍了在SpringBoot项目中如何使用@ComponentScan注解和自定义过滤器实现不加载某些Bean的方法,本文通过实... 使用@ComponentScan注解中的@ComponentScan.Filter标记不加载。@C

MySQL中删除重复数据SQL的三种写法

《MySQL中删除重复数据SQL的三种写法》:本文主要介绍MySQL中删除重复数据SQL的三种写法,文中通过代码示例讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下... 目录方法一:使用 left join + 子查询删除重复数据(推荐)方法二:创建临时表(需分多步执行,逻辑清晰,但会

Python按条件批量删除TXT文件行工具

《Python按条件批量删除TXT文件行工具》这篇文章主要为大家详细介绍了Python如何实现按条件批量删除TXT文件中行的工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.简介2.运行效果3.相关源码1.简介一个由python编写android的可根据TXT文件按条件批

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

电脑桌面文件删除了怎么找回来?别急,快速恢复攻略在此

在日常使用电脑的过程中,我们经常会遇到这样的情况:一不小心,桌面上的某个重要文件被删除了。这时,大多数人可能会感到惊慌失措,不知所措。 其实,不必过于担心,因为有很多方法可以帮助我们找回被删除的桌面文件。下面,就让我们一起来了解一下这些恢复桌面文件的方法吧。 一、使用撤销操作 如果我们刚刚删除了桌面上的文件,并且还没有进行其他操作,那么可以尝试使用撤销操作来恢复文件。在键盘上同时按下“C

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists