跳至主要內容

740, 删除并获得点数

Mike大约 3 分钟dynamic programmingmediumarrayhash tabledynamic programming

一、题目描述

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

每次操作中,选择任意一个nums[i],删除它并获得nums[i]的点数。之后,你必须删除所有等于nums[i] - 1nums[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个点数,接着要删除两个24
之后,再次删除3获得3个点数,再次删除3获得3个点数。
总共获得9个点数。

提示

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

相关主题

  • 数组
  • 哈希表
  • 动态规划

二、题解

方法 1: 动态规划

/// Time Complexity: O(N + M)
/// Space Complexity: O(M)
pub fn delete_and_earn(nums: Vec<i32>) -> i32 {
    let mut max_val = 0;
    for num in &nums {
        max_val = max(max_val, *num);
    }

    let mut sum = vec![0; max_val as usize + 1];
    for num in nums {
        sum[num as usize] += num;
    }

    let rob = || {
        let (mut first, mut second) = (sum[0], max(sum[0], sum[1]));
        for i in 2..sum.len() {
            (first, second) = (second, max(first + sum[i], second));
        }
        second
    };

    rob()
}

方法 2: 排序 + 动态规划

/// Time Complexity: O(N*log(N))
/// Space Complexity: O(N)
pub fn delete_and_earn(nums: Vec<i32>) -> i32 {
    let mut res = 0;
    nums.sort_unstable();

    let mut sum = vec![nums[0]; 1];
    let rob: fn(&mut [i32]) -> i32 = |sum| {
        let len = sum.len();
        if len == 1 {
            return sum[0];
        }
        let (mut first, mut second) = (sum[0], max(sum[0], sum[1]));
        for i in 2..len {
            (first, second) = (second, max(first + sum[i], second));
        }
        second
    };

    for i in 1..nums.len() {
        let val = nums[i];
        if val == nums[i - 1] {
            sum.last_mut().map(|last| *last += val);
        } else if val == nums[i - 1] + 1 {
            sum.push(val);
        } else {
            res += rob(&mut sum);
            sum.truncate(1);
            sum[0] = val;
        }
    }

    res += rob(&mut sum);
    res
}