Open In App

Last remaining element by removing values closest to half of Array sum

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of size N, the task is to find the last element remaining after removing all elements closest to sum/2 sequentially where sum is the array sum.

Note: If sum/2 is decimal, then its floor value is considered for the operation and if there is a tie between the closest elements then delete the smaller one.

Examples:

Input:  N = 4, arr[] = {1, 3, 5, 7}
Output: 5
Explanation: Iteration 1: {1, 3, 5, 7}, sum = 16, sum/2 = 8, delete 7
Iteration 2: {1, 3, 5}, sum = 9, sum/2 = 4, delete 3
Iteration 3: {1, 5}, sum = 6, sum/2 = 3, delete 1
At last only element 5 is present.

Input: N = 4, arr[] = {1, 2, 3, 4}
Output: 2
Explanation: Iteration 1: {1, 2, 3, 4}, sum = 10, sum/2 = 5, delete 4
Iteration 2: {1, 2, 3}, sum = 6, sum/2 = 3, delete 3
Iteration 3: {1, 2}, sum = 3, sum/2 = 1, delete 1
At last only element 2 is present.

 

Approach: To solve the problem follow the below idea:

The problem deals with the efficient searching of the elements within the array or vector and can be achieved by binary search
Use a loop and calculate the sum of the array and delete the element that is closest to sum/2. Execute the loop till there is only one element left.

Follow the given steps to solve the problem:

  • Sort the given N integers.
  • Traverse and find the sum of all integers.
  • While the size is greater than 1, find the index of the closest element to sum/2
    • Apply binary search for the purpose and in each iteration update the difference to get the closest element.
    • Subtract arr[index] from the sum.
    • Erase the element from vector arr at position index.
  • Return the only remaining element of the vector.

Below is the implementation for the above approach:

C++14




// C++ program for above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the position in the
// vector whose value is closest to the key,
// using binary search
int correctPOS(vector<int>& arr, int n, int key)
{
    int low = 0, high = n - 1, mid;
 
    // Base cases
    if (key <= arr[0])
        return 0;
    else if (key >= arr[n - 1])
        return n - 1;
 
    // Implementation of binary search
    while (low <= high) {
 
        mid = low + (high - low) / 2;
 
        // If the value of arr[mid] is
        // equal to the key, return mid
        if (arr[mid] == key)
            return mid;
 
        // If this is the case
        // then ignore right half
        else if (key < arr[mid]) {
            high = mid - 1;
 
            // Condition to check if the key is
            // in-between arr[mid] and arr[mid-1]
            if (mid > 0 && arr[mid - 1] < key) {
 
                if (abs(key - arr[mid - 1])
                    <= abs(arr[mid] - key))
                    return mid - 1;
                else
                    return mid;
            }
        }
 
        // If this is the case
        // then ignore left half
        else {
            low = mid + 1;
 
            // Condition to check if the key
            // is in-between arr[mid] and arr[mid+1]
            if (mid + 1 < n && arr[mid + 1] > key) {
 
                if (abs(key - arr[mid])
                    <= abs(arr[mid + 1] - key))
                    return mid;
                else
                    return mid + 1;
            }
        }
    }
 
    return mid;
}
 
// Function to find the last
// remaining element
int FindVirus(vector<int>& arr)
{
    int i, index, n = arr.size();
    long long sum = 0;
 
    // Sort the input vector
    sort(arr.begin(), arr.end());
 
    // Traverse the vector to calculate
    // the sum of elements
    for (i = 0; i < n; i++)
        sum += arr[i];
 
    // Run a while loop, while size of vector
    // is greater than one
    while (arr.size() > 1) {
        int index = correctPOS(arr, arr.size(),
                               sum / 2);
        sum -= arr[index];
        arr.erase(arr.begin() + index);
    }
 
    // Return the remaining element
    return arr[0];
}
 
// Driver code
int main()
{
    vector<int> arr = { 1, 3, 5, 7 };
 
    // Function call
    cout << FindVirus(arr);
    return 0;
}


Java




// Java program for above approach
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Function to find the position in the vector whose
    // value is closest to the key, using binary search
    public static int correctPOS(List<Integer> arr, int n,
                                 int key)
    {
        int low = 0, high = n - 1;
        int mid = 0;
        // Base cases
        if (key <= arr.get(0)) {
            return 0;
        }
        else if (key >= arr.get(n - 1)) {
            return n - 1;
        }
        // Implementation of binary search
        while (low <= high) {
            mid = low + (high - low) / 2;
            // If the value of arr[mid] is equal to the key,
            // return mid
            if (arr.get(mid) == key) {
                return mid;
            }
            // If this is the case then ignore right half
            else if (key < arr.get(mid)) {
                high = mid - 1;
                // Condition to check if the key is
                // in-between arr[mid] and arr[mid-1]
                if (mid > 0 && arr.get(mid - 1) < key) {
                    if (Math.abs(key - arr.get(mid - 1))
                        <= Math.abs(arr.get(mid)) - key) {
                        return mid - 1;
                    }
                    else {
                        return mid;
                    }
                }
            }
            // If this is the case then ignore left half
            else {
                low = mid + 1;
                // Condition to check if the key is
                // in-between arr[mid] and arr[mid+1]
                if (mid + 1 < n && arr.get(mid + 1) > key) {
                    if (Math.abs(key - arr.get(mid))
                        <= Math.abs(arr.get(mid + 1)
                                    - key)) {
                        return mid;
                    }
                    else {
                        return mid + 1;
                    }
                }
            }
        }
        return mid;
    }
 
    // Function to find the last remaining element.
    public static int FindVirus(List<Integer> arr)
    {
        int i, index, n = arr.size();
        int sum = 0;
        // Sort the array
        Collections.sort(arr);
        // Traverse the array to calculate the sum of
        // elements
        for (i = 0; i < n; i++) {
            sum += arr.get(i);
        }
        // Run a while loop, while size of array is greater
        // than one
        while (arr.size() > 1) {
            index = correctPOS(arr, arr.size(), sum / 2);
            sum -= arr.get(index);
            arr.remove(index);
        }
        // Return the remaining element
        return arr.get(0);
    }
 
    public static void main(String[] args)
    {
        List<Integer> arr = new ArrayList<Integer>();
        arr.add(1);
        arr.add(3);
        arr.add(5);
        arr.add(7);
 
        // Function call
        System.out.print(FindVirus(arr));
    }
}
 
// This code is contributed by lokesh (lokeshmvs21).


Python3




# Python program for above approach
 
# Function to find the position in the
# vector whose value is closest to the key,
# using binary search
 
 
def correctPOS(arr, n, key):
    low = 0
    high = n - 1
    mid = 0
 
    # Base cases
    if (key <= arr[0]):
        return 0
    elif (key >= arr[n - 1]):
        return n - 1
 
    # Implementation of binary search
    while (low <= high):
        mid = low + (high - low) // 2
        # If the value of arr[mid] is
        # equal to the key, return mid
        if (arr[mid] == key):
            return mid
        # If this is the case
        # then ignore right half
        elif (key < arr[mid]):
            high = mid - 1
 
        # Condition to check if the key is
        # in-between arr[mid] and arr[mid-1]
        if (mid > 0 and arr[mid - 1] < key):
            if (abs(key - arr[mid - 1]) <= abs(arr[mid] - key)):
                return mid - 1
            else:
                return mid
 
        # If this is the case
        # then ignore left half
        else:
            low = mid + 1
            # Condition to check if the key
            # is in-between arr[mid] and arr[mid+1]
            if (mid + 1 < n and arr[mid + 1] > key):
                if (abs(key - arr[mid]) <= abs(arr[mid + 1] - key)):
                    return mid
                else:
                    return mid + 1
 
    return mid
 
# Function to find the last
# remaining element
 
 
def FindVirus(arr):
    i = 0
    index = 0
    n = len(arr)
    sum = 0
 
    # Sort the input vector
    arr.sort()
 
    # Traverse the vector to calculate
    # the sum of elements
    for i in range(n):
        sum += arr[i]
 
    # Run a while loop, while size of vector
    # is greater than one
    while (len(arr) > 1):
        index = correctPOS(arr, len(arr), sum / 2)
        sum -= arr[index]
        del arr[index]
    # Return the remaining element
    return arr[0]
 
 
# Driver code
if __name__ == "__main__":
    arr = [1, 3, 5, 7]
 
    # Function call
    print(FindVirus(arr))
 
# This code is contributed by Rohit Pradhan


C#




// C# program for above approach
 
 
using System;
using System.Collections.Generic;
 
public class GFG {
 
    // Function to find the position in the vector whose
    // value is closest to the key, using binary search
    public static int correctPOS(List<int> arr, int n,
                                 int key)
    {
        int low = 0, high = n - 1;
        int mid = 0;
        // Base cases
        if (key <= arr[0]) {
            return 0;
        }
        else if (key >= arr[n - 1]) {
            return n - 1;
        }
        // Implementation of binary search
        while (low <= high) {
            mid = low + (high - low) / 2;
            // If the value of arr[mid] is equal to the key,
            // return mid
            if (arr[mid] == key) {
                return mid;
            }
            // If this is the case then ignore right half
            else if (key < arr[mid]) {
                high = mid - 1;
                // Condition to check if the key is
                // in-between arr[mid] and arr[mid-1]
                if (mid > 0 && arr[mid - 1] < key) {
                    if (Math.Abs(key - arr[mid - 1])
                        <= Math.Abs(arr[mid]) - key) {
                        return mid - 1;
                    }
                    else {
                        return mid;
                    }
                }
            }
            // If this is the case then ignore left half
            else {
                low = mid + 1;
                // Condition to check if the key is
                // in-between arr[mid] and arr[mid+1]
                if (mid + 1 < n && arr[mid + 1] > key) {
                    if (Math.Abs(key - arr[mid])
                        <= Math.Abs(arr[mid + 1]
                                    - key)) {
                        return mid;
                    }
                    else {
                        return mid + 1;
                    }
                }
            }
        }
        return mid;
    }
 
    // Function to find the last remaining element.
    public static int FindVirus(List<int> arr)
    {
        int i, index, n = arr.Count;
        int sum = 0;
        // Sort the array
        arr.Sort();
        // Traverse the array to calculate the sum of
        // elements
        for (i = 0; i < n; i++) {
            sum += arr[i];
        }
        // Run a while loop, while size of array is greater
        // than one
        while (arr.Count > 1) {
            index = correctPOS(arr, arr.Count, sum / 2);
            sum -= arr[index];
            arr.RemoveAt(index);
        }
        // Return the remaining element
        return arr[0];
    }
 
    public static void Main(String[] args)
    {
        List<int> arr = new List<int>();
        arr.Add(1);
        arr.Add(3);
        arr.Add(5);
        arr.Add(7);
 
        // Function call
        Console.Write(FindVirus(arr));
    }
}
 
 
// This code contributed by shikhasingrajput


Javascript




<script>
        // JavaScript code for the above approach
 
    // Function to find the position in the vector whose
    // value is closest to the key, using binary search
    function correctPOS(arr, n, key)
    {
        let low = 0, high = n - 1;
        let mid = 0;
        // Base cases
        if (key <= arr[0]) {
            return 0;
        }
        else if (key >= arr[n - 1]) {
            return n - 1;
        }
        // Implementation of binary search
        while (low <= high) {
            mid = low + Math.floor((high - low) / 2);
            // If the value of arr[mid] is equal to the key,
            // return mid
            if (arr[mid] == key) {
                return mid;
            }
            // If this is the case then ignore right half
            else if (key < arr[mid]) {
                high = mid - 1;
                // Condition to check if the key is
                // in-between arr[mid] and arr[mid-1]
                if (mid > 0 && arr[mid - 1] < key) {
                    if (Math.abs(key - arr[mid - 1])
                        <= Math.abs(arr[mid]) - key) {
                        return mid - 1;
                    }
                    else {
                        return mid;
                    }
                }
            }
            // If this is the case then ignore left half
            else {
                low = mid + 1;
                // Condition to check if the key is
                // in-between arr[mid] and arr[mid+1]
                if (mid + 1 < n && arr[mid + 1] > key) {
                    if (Math.abs(key - arr[mid])
                        <= Math.abs(arr[mid + 1]
                                    - key)) {
                        return mid;
                    }
                    else {
                        return mid + 1;
                    }
                }
            }
        }
        return mid;
    }
     
     // Function to find the last remaining element.
    function FindVirus(arr)
    {
        let i, index, n = arr.length;
        let sum = 0;
        // Sort the array
        arr.sort((a,b) => b-a);
         
        // Traverse the array to calculate the sum of
        // elements
        for (i = 0; i < n; i++) {
            sum += arr[i];
        }
        // Run a while loop, while size of array is greater
        // than one
        while (arr.length > 1) {
            index = correctPOS(arr, arr.length, Math.floor(sum / 2));
            sum -= arr[index];
            arr.pop(index);
        }
        // Return the remaining element
        return (arr[0]+1);
    }
 
// Driver Code
        let arr = [];
        arr.push(1);
        arr.push(3);
        arr.push(5);
        arr.push(7);
 
        // Function call
        document.write(FindVirus(arr));
     
    // This code is contributed by sanjoy_62.
    </script>


Output

8

Time Complexity: O(N2)
Auxiliary Space: O(1)



Last Updated : 01 Sep, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads