740. Delete and Earn
leetcode medium
Task
Вам дан целочисленный массив nums. Вы хотите максимизировать количество очков, выполнив следующую операцию любое количество раз: Выберите любой элемент nums[i] и удалите его, чтобы заработать nums[i] очков. После этого вы должны удалить каждый элемент, равный nums[i] - 1, и каждый элемент, равный nums[i] + 1. Верните максимальное количество очков, которое вы можете заработать, применив вышеуказанную операцию некоторое количество раз.
Пример:
Input: nums = [3,4,2]
Output: 6
C# solution
matched/originalusing System;
using System.Collections.Generic;
using System.Linq;
public class Solution {
public int DeleteAndEarn(int[] nums) {
var count = new Dictionary<int, int>();
foreach (var num in nums) {
if (!count.ContainsKey(num)) {
count[num] = 0;
}
count[num]++;
}
int avoid = 0, using = 0, prev = -1;
foreach (var num in count.Keys.OrderBy(x => x)) {
if (num - 1 != prev) {
int newAvoid = Math.Max(avoid, using);
using = num * count[num] + Math.Max(avoid, using);
avoid = newAvoid;
} else {
int newAvoid = Math.Max(avoid, using);
using = num * count[num] + avoid;
avoid = newAvoid;
}
prev = num;
}
return Math.Max(avoid, using);
}
}C++ solution
auto-draft, review before submit#include <bits/stdc++.h>
using namespace std;
// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
class Solution {
public:
public int DeleteAndEarn(vector<int>& nums) {
var count = new unordered_map<int, int>();
foreach (var num in nums) {
if (!count.count(num)) {
count[num] = 0;
}
count[num]++;
}
int avoid = 0, using = 0, prev = -1;
foreach (var num in count.Keys.OrderBy(x => x)) {
if (num - 1 != prev) {
int newAvoid = max(avoid, using);
using = num * count[num] + max(avoid, using);
avoid = newAvoid;
} else {
int newAvoid = max(avoid, using);
using = num * count[num] + avoid;
avoid = newAvoid;
}
prev = num;
}
return max(avoid, using);
}
}Java solution
matched/originalimport java.util.*;
public class Solution {
public int deleteAndEarn(int[] nums) {
Map<Integer, Integer> count = new HashMap<>();
for (int num : nums) {
count.put(num, count.getOrDefault(num, 0) + 1);
}
int avoid = 0, using = 0, prev = -1;
for (int num : count.keySet().stream().sorted().mapToInt(Integer::intValue).toArray()) {
if (num - 1 != prev) {
int newAvoid = Math.max(avoid, using);
using = num * count.get(num) + Math.max(avoid, using);
avoid = newAvoid;
} else {
int newAvoid = Math.max(avoid, using);
using = num * count.get(num) + avoid;
avoid = newAvoid;
}
prev = num;
}
return Math.max(avoid, using);
}
}JavaScript solution
matched/originalvar deleteAndEarn = function(nums) {
const count = {};
nums.forEach(num => count[num] = (count[num] || 0) + 1);
let prev = null;
let avoid = 0, using = 0;
Object.keys(count).sort((a, b) => a - b).forEach(num => {
num = parseInt(num);
if (num - 1 !== prev) {
const newAvoid = Math.max(avoid, using);
using = num * count[num] + Math.max(avoid, using);
avoid = newAvoid;
} else {
const newAvoid = Math.max(avoid, using);
using = num * count[num] + avoid;
avoid = newAvoid;
}
prev = num;
});
return Math.max(avoid, using);
};Python solution
matched/originaldef deleteAndEarn(nums):
from collections import Counter
count = Counter(nums)
prev = None
avoid = using = 0
for num in sorted(count):
if num - 1 != prev:
new_avoid, new_using = max(avoid, using), num * count[num] + max(avoid, using)
else:
new_avoid, new_using = max(avoid, using), num * count[num] + avoid
avoid, using = new_avoid, new_using
prev = num
return max(avoid, using)Go solution
matched/originalpackage main
import "sort"
func deleteAndEarn(nums []int) int {
count := make(map[int]int)
for _, num := range nums {
count[num]++
}
uniqueNums := make([]int, 0, len(count))
for num := range count {
uniqueNums = append(uniqueNums, num)
}
sort.Ints(uniqueNums)
avoid, using, prev := 0, 0, -1
for _, num := range uniqueNums {
if num-1 != prev {
newAvoid := max(avoid, using)
using = num*count[num] + max(avoid, using)
avoid = newAvoid
} else {
newAvoid := max(avoid, using)
using = num*count[num] + avoid
avoid = newAvoid
}
prev = num
}
return max(avoid, using)
}
func max(a, b int) int {
if a > b {
return a
}
return b
}Explanation
Algorithm
Подсчитайте количество каждого числа в массиве nums.
Используйте динамическое программирование для расчета максимальных очков, которые можно заработать, используя накопленный результат для чисел, меньших текущего. Добавьте текущий день в стек.
Для каждого числа num в nums, учитывайте два случая: не брать число или взять число и добавить его очки.
😎