Maximize the sum of selected numbers from an array to make it empty


We will be given an array and have to choose an element from it and add that element to the sum. After adding that element to the sum, we have to remove three elements from the array if they exist current number, current number -1, and current number + 1. By this method we will make the array empty and will get a sum. At the end, we have to make the sum maximum.

Input: [ 1, 2, 3]
Output: 4 

Explanation

At first, we can have three moves, delete 1, 2, or 3.

  • Let us delete 1 then we have to delete 0, 1, and 2 (if any of them is present, at least one of them must be present). We will get the sum equals to 1 and the array will be left with only 3. After deleting 3 we will get the sum equals to 4.

  • Let us delete 2 then we have to delete 1, 2, and 3 and final sum will be 2.

  • Let us delete 3 first, then sum will be 3, and the array will be 1. After deleting the 1 we will get the sum as 4.

Input: [ 1, 2, 2, 2, 3, 3]
Output: 8

We can delete first two three that will be given us 6 and two two’s will be deleted with that.

After that we will delete one remaining two and get the 8 as the answer.

Approach 1

In this approach, we will get the maximum element present in the array first to get the frequency of the elements present in the array.

Later we will create an array to store the frequency of the elements present in the given array.

We will traverse from the last element of the frequency array, as we have to delete the current, one minus and one plus element from the array this will always save the number which is one greater, leads to the maximum sum as the result.

Example

#include <iostream>
using namespace std;
int maxElement(int arr[], int n){
   int mx = arr[0]; // defining variable to store the maximum element
   for(int i=1; i<n; i++){
      if(mx < arr[i]){
         mx = arr[i];
      }
   }
   return mx;
}
int maxSum(int arr[], int n){
   // getting the maximum element first 
   int mx = maxElement(arr,n);
   // creating array of maximum size to store frequecny of the elements 
   int freq[mx+1] = {0}; // defining each element as zero first 
   // getting the frequecny of the elements 
   for(int i=0; i<n; i++){
      freq[arr[i]]++;
   }
   int ans = 0; // variable to store the answer 
   // traversing over the array 
   for(int i=mx; i>0; i--){
      if(freq[i] > 0){
         ans += freq[i]*i;
         freq[i-1] -= freq[i];
      }
   }
   return ans;
}
int main(){
   int n; // number of elements in the given array 
   int arr[] = { 1, 2, 2, 2, 3, 3}; // given array
   n = sizeof(arr)/sizeof(arr[0]);
   // calling the function to get the answer 
   cout<<"The maximum sum we can get by deleting the elements is: "<<maxSum(arr,n);
}

Output

The maximum sum we can get by deleting the elements is: 8

Time and Space Complexity

The time complexity of the above code is O(N), where N is the maximum element that is present in the given array.

The space complexity of the above code is same as the time complexity that is O(N) as we have created an array to store frequency of the elements.

The previous given approach has one problem that if the largest element is very large than it will take a lot of time and space to solve the problem. To handle this problem, we have next approach.

Map Approach

In this approach, we will create the map to store the frequency of the elements instead of the array and the idea is the same.

Example

#include <bits/stdc++.h>
using namespace std;
int maxSum(int arr[], int n){
   // sorting the array to travers over the map from last 
   sort(arr,arr+n);
   // creating the map 
   unordered_map<int,int>mp;
   // getting the frequecny of the elements 
   for(int i=n-1; i>=0; i--){
      mp[arr[i]]++;
   }
   int ans = 0; // variable to store the answer 
   // traversing over the array 
   for(int i=n-1; i>=0; i--){
      if (mp.count(arr[i])) {
         ans += arr[i];
         mp[arr[i]]--;
         // if element frequency in map become zero
         // than remove that element
         if (mp[arr[i]] == 0){
            mp.erase(arr[i]);
         }
         if (mp.count(arr[i] - 1)){
            mp[arr[i] - 1]--;
            if (mp[arr[i] - 1] == 0){
               mp.erase(arr[i] - 1);
            }
         }
      }
   }
   return ans;
}
int main(){
   int n; // number of elements in the given array 
   int arr[] = { 1, 2, 2, 2, 3, 3}; // given array
   n = sizeof(arr)/sizeof(arr[0]);
   // calling the function to get the answer 
   cout<<"The maximum sum we can get by deleting the elements is: "<<maxSum(arr,n);
}

Output

The maximum sum we can get by deleting the elements is: 8

Time and Space Complexity

The time complexity of the above code is O(N), where N is the number of elements present in the given array.

The space complexity of the above code is same as the time complexity that is O(N) as we have created a map to store frequency of the elements.

Conclusion

In this tutorial we have implemented a C++ program to maximize the sum of selected numbers from an array to make it empty. We have to choose an element from it and add that element to the sum. After adding that element to the sum, we have to remove three elements from the array if they exist current number, current number -1, and current number + 1. We have implemented two frequency base approaches with linear time and space complexity.

Updated on: 16-May-2023

123 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements