leetcode笔记(六)740. Delete and Earn

  • 题目描述

Given an array nums of integers, you can perform operations on the array.

In each operation, you pick any nums[i] and delete it to earn nums[i] points. After, you must delete every element equal to nums[i] - 1 or nums[i] + 1.

You start with 0 points. Return the maximum number of points you can earn by applying such operations.

Example 1:

Input: nums = [3, 4, 2]
Output: 6
Explanation: 
Delete 4 to earn 4 points, consequently 3 is also deleted.
Then, delete 2 to earn 2 points. 6 total points are earned. 

Example 2:

Input: nums = [2, 2, 3, 3, 3, 4]
Output: 9
Explanation: 
Delete 3 to earn 3 points, deleting both 2's and the 4.
Then, delete 3 again to earn 3 points, and 3 again to earn 3 points.
9 total points are earned. 

Note:

  1. The length of nums is at most 20000.
  2. Each element nums[i] is an integer in the range [1, 10000].
  • 解题思路

看题目,可以意识到是动态规划类型的题目,但不知道怎么写迭代式子,就是相不清楚状态。所以,一开始心虚的按照自己的贪婪算法实现了下,结果就是代码极多,但结果不能对~

无奈,开始查阅资料,找到了一篇比较靠谱的博客。借鉴他的思路,自己努力写了下动态规划的实现。思路的关键在于:

  1. 取出一个数,其收益为 数的频数 × 数的值。按照规则,取出一个,必然取出该值的所有数。
  2. 两个状态,取出当前数的最大收益(maxFetch),不取当前数的最大收益(maxNoFetch)。
  3. 初始状态:
    •  maxFetch = 0, maxNoFetch = 0;
  4. 当前状态与上一状态的关系
    • 不取当前数,则为上一状态的最大值(max(prevMaxFetch, prevMaxNoFetch))。
    • 取出当前数,若数和上一状态的数关联(+/- 1),则为prevMaxNoFetch + 取出数的收益。否则,为max(prevMaxFetch, prevMaxNoFetch) + 取出数的收益。
  • 示例代码
class Solution {
public:
    
    int deleteAndEarn(vector<int>& nums) {
        map<int, int> freqs;
        int size = nums.size();
        for(int i = 0; i < size; i++)
        {
            int curr = nums[i];
            // remember frequences for curr
            if(freqs.find(curr) == freqs.end())
            {
                freqs[curr] = 1;
            }
            else
            {
                freqs[curr] += 1;
            }
            
        }
        
        int maxFetch = 0, maxNoFetch = 0;
        int prevMaxFetch = 0, prevMaxNoFetch = 0;
        map<int, int>::iterator prevChoice;
        map<int, int>::iterator currChoice;
        // calculate maximum according to previous status
        for(currChoice = freqs.begin(); currChoice != freqs.end(); ++currChoice) 
        {
            // initiate
            if(currChoice == freqs.begin()) 
            {
                // get this number
                maxFetch = currChoice->first * currChoice->second;
                // do not get this number
                maxNoFetch = 0;
            }
            // transferring
            else 
            {
                prevMaxFetch = maxFetch;
                prevMaxNoFetch = maxNoFetch;
                // do not get the number
                maxNoFetch = max(prevMaxFetch, prevMaxNoFetch);
                // get this number
                if(currChoice->first == prevChoice -> first + 1 || currChoice->first == prevChoice -> first - 1) {
                    // related -> must not fetch previous node
                    maxFetch = prevMaxNoFetch + currChoice->first * currChoice->second;
                }
                else 
                {   // non related
                    maxFetch = maxNoFetch + currChoice->first * currChoice->second;
                }
            }
            
            prevChoice = currChoice;
        }

        
        return max(maxFetch, maxNoFetch);
    }
};

猜你喜欢

转载自www.cnblogs.com/niuxu18/p/note_leetcode_6.html