classSolution { private: introb(vector<int> &nums){ int size = nums.size(); int first = nums[0], second = max(nums[0], nums[1]); for (int i = 2; i < size; i++) { int temp = second; second = max(first + nums[i], second); first = temp; } return second; }
public: intdeleteAndEarn(vector<int> &nums){ int maxVal = 0; for (int val : nums) { maxVal = max(maxVal, val); } vector<int> sum(maxVal + 1); for (int val : nums) { sum[val] += val; } returnrob(sum); } };
publicclassSolution { publicintDeleteAndEarn(int[] nums) { int maxVal = 0; foreach (int val in nums) { maxVal = Math.Max(maxVal, val); } int[] sum = newint[maxVal + 1]; foreach (int val in nums) { sum[val] += val; } return Rob(sum); }
publicintRob(int[] nums) { int size = nums.Length; int first = nums[0], second = Math.Max(nums[0], nums[1]); for (int i = 2; i < size; i++) { int temp = second; second = Math.Max(first + nums[i], second); first = temp; } return second; } }
funcdeleteAndEarn(nums []int)int { maxVal := 0 for _, val := range nums { maxVal = max(maxVal, val) } sum := make([]int, maxVal+1) for _, val := range nums { sum[val] += val } return rob(sum) }
funcrob(nums []int)int { first, second := nums[0], max(nums[0], nums[1]) for i := 2; i < len(nums); i++ { first, second = second, max(first+nums[i], second) } return second }
funcmax(a, b int)int { if a > b { return a } return b }
[sol1-Python3]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classSolution: defdeleteAndEarn(self, nums: List[int]) -> int: maxVal = max(nums) total = [0] * (maxVal + 1) for val in nums: total[val] += val defrob(nums: List[int]) -> int: size = len(nums) first, second = nums[0], max(nums[0], nums[1]) for i inrange(2, size): first, second = second, max(first + nums[i], second) return second return rob(total)
introb(int *nums, int numsSize) { int first = nums[0], second = fmax(nums[0], nums[1]); for (int i = 2; i < numsSize; i++) { int temp = second; second = fmax(first + nums[i], second); first = temp; } return second; }
intdeleteAndEarn(int *nums, int numsSize) { int maxVal = 0; for (int i = 0; i < numsSize; i++) { maxVal = fmax(maxVal, nums[i]); } int sum[maxVal + 1]; memset(sum, 0, sizeof(sum)); for (int i = 0; i < numsSize; i++) { sum[nums[i]] += nums[i]; } return rob(sum, maxVal + 1); }
var deleteAndEarn = function(nums) { let maxVal = 0; for (const val of nums) { maxVal = Math.max(maxVal, val); } const sum = newArray(maxVal + 1).fill(0); for (const val of nums) { sum[val] += val; } returnrob(sum); };
constrob = (nums) => { const size = nums.length; let first = nums[0], second = Math.max(nums[0], nums[1]); for (let i = 2; i < size; i++) { let temp = second; second = Math.max(first + nums[i], second); first = temp; } return second; }
复杂度分析
时间复杂度:O(N+M),其中 N 是数组 nums 的长度,M 是 nums 中元素的最大值。
空间复杂度:O(M)。
方法二:排序 + 动态规划
注意到若 nums 中不存在某个元素 x,则选择任一小于 x 的元素不会影响到大于 x 的元素的选择。因此我们可以将 nums 排序后,将其划分成若干连续子数组,子数组内任意相邻元素之差不超过 1。对每个子数组按照方法一的动态规划过程计算出结果,累加所有结果即为答案。
classSolution { private: introb(vector<int> &nums){ int size = nums.size(); if (size == 1) { return nums[0]; } int first = nums[0], second = max(nums[0], nums[1]); for (int i = 2; i < size; i++) { int temp = second; second = max(first + nums[i], second); first = temp; } return second; }
public: intdeleteAndEarn(vector<int> &nums){ int n = nums.size(); int ans = 0; sort(nums.begin(), nums.end()); vector<int> sum = {nums[0]}; for (int i = 1; i < n; ++i) { int val = nums[i]; if (val == nums[i - 1]) { sum.back() += val; } elseif (val == nums[i - 1] + 1) { sum.push_back(val); } else { ans += rob(sum); sum = {val}; } } ans += rob(sum); return ans; } };
publicclassSolution { publicintDeleteAndEarn(int[] nums) { int n = nums.Length; int ans = 0; Array.Sort(nums); IList<int> sum = new List<int>(); sum.Add(nums[0]); int size = 1; for (int i = 1; i < n; ++i) { int val = nums[i]; if (val == nums[i - 1]) { sum[size - 1] += val; } elseif (val == nums[i - 1] + 1) { sum.Add(val); ++size; } else { ans += Rob(sum); sum.Clear(); sum.Add(val); size = 1; } } ans += Rob(sum); return ans; }
publicintRob(IList<int> nums) { int size = nums.Count; if (size == 1) { return nums[0]; } int first = nums[0], second = Math.Max(nums[0], nums[1]); for (int i = 2; i < size; i++) { int temp = second; second = Math.Max(first + nums[i], second); first = temp; } return second; } }
funcdeleteAndEarn(nums []int) (ans int) { sort.Ints(nums) sum := []int{nums[0]} for i := 1; i < len(nums); i++ { if val := nums[i]; val == nums[i-1] { sum[len(sum)-1] += val } elseif val == nums[i-1]+1 { sum = append(sum, val) } else { ans += rob(sum) sum = []int{val} } } ans += rob(sum) return }
funcrob(nums []int)int { iflen(nums) == 1 { return nums[0] } first, second := nums[0], max(nums[0], nums[1]) for i := 2; i < len(nums); i++ { first, second = second, max(first+nums[i], second) } return second }
funcmax(a, b int)int { if a > b { return a } return b }
first, second = nums[0], max(nums[0], nums[1]) for i inrange(2, size): first, second = second, max(first + nums[i], second) return second n = len(nums) ans = 0 nums.sort() total = [nums[0]]
for i inrange(1, n): val = nums[i] if val == nums[i - 1]: total[-1] += val elif val == nums[i - 1] + 1: total.append(val) else: ans += rob(total) total = [val] ans += rob(total) return ans
introb(int *nums, int numsSize) { if (numsSize == 1) { return nums[0]; } int first = nums[0], second = fmax(nums[0], nums[1]); for (int i = 2; i < numsSize; i++) { int temp = second; second = fmax(first + nums[i], second); first = temp; } return second; }
intcmp(int *a, int *b) { return *a - *b; }
intdeleteAndEarn(int *nums, int numsSize) { int ans = 0; qsort(nums, numsSize, sizeof(int), cmp); int sum[numsSize], sumSize = 0; sum[sumSize++] = nums[0]; for (int i = 1; i < numsSize; ++i) { int val = nums[i]; if (val == nums[i - 1]) { sum[sumSize - 1] += val; } elseif (val == nums[i - 1] + 1) { sum[sumSize++] = val; } else { ans += rob(sum, sumSize); sumSize = 0; sum[sumSize++] = val; } } ans += rob(sum, sumSize); return ans; }