Last remaining element by removing values closest to half of Array sum
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
#include <bits/stdc++.h>
using namespace std;
int correctPOS(vector< int >& arr, int n, int key)
{
int low = 0, high = n - 1, mid;
if (key <= arr[0])
return 0;
else if (key >= arr[n - 1])
return n - 1;
while (low <= high) {
mid = low + (high - low) / 2;
if (arr[mid] == key)
return mid;
else if (key < arr[mid]) {
high = 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;
}
}
else {
low = 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;
}
int FindVirus(vector< int >& arr)
{
int i, index, n = arr.size();
long long sum = 0;
sort(arr.begin(), arr.end());
for (i = 0; i < n; i++)
sum += arr[i];
while (arr.size() > 1) {
int index = correctPOS(arr, arr.size(),
sum / 2);
sum -= arr[index];
arr.erase(arr.begin() + index);
}
return arr[0];
}
int main()
{
vector< int > arr = { 1, 3, 5, 7 };
cout << FindVirus(arr);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
public static int correctPOS(List<Integer> arr, int n,
int key)
{
int low = 0 , high = n - 1 ;
int mid = 0 ;
if (key <= arr.get( 0 )) {
return 0 ;
}
else if (key >= arr.get(n - 1 )) {
return n - 1 ;
}
while (low <= high) {
mid = low + (high - low) / 2 ;
if (arr.get(mid) == key) {
return mid;
}
else if (key < arr.get(mid)) {
high = 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;
}
}
}
else {
low = 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;
}
public static int FindVirus(List<Integer> arr)
{
int i, index, n = arr.size();
int sum = 0 ;
Collections.sort(arr);
for (i = 0 ; i < n; i++) {
sum += arr.get(i);
}
while (arr.size() > 1 ) {
index = correctPOS(arr, arr.size(), sum / 2 );
sum -= arr.get(index);
arr.remove(index);
}
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 );
System.out.print(FindVirus(arr));
}
}
|
Python3
def correctPOS(arr, n, key):
low = 0
high = n - 1
mid = 0
if (key < = arr[ 0 ]):
return 0
elif (key > = arr[n - 1 ]):
return n - 1
while (low < = high):
mid = low + (high - low) / / 2
if (arr[mid] = = key):
return mid
elif (key < arr[mid]):
high = 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
else :
low = 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
def FindVirus(arr):
i = 0
index = 0
n = len (arr)
sum = 0
arr.sort()
for i in range (n):
sum + = arr[i]
while ( len (arr) > 1 ):
index = correctPOS(arr, len (arr), sum / 2 )
sum - = arr[index]
del arr[index]
return arr[ 0 ]
if __name__ = = "__main__" :
arr = [ 1 , 3 , 5 , 7 ]
print (FindVirus(arr))
|
C#
using System;
using System.Collections.Generic;
public class GFG {
public static int correctPOS(List< int > arr, int n,
int key)
{
int low = 0, high = n - 1;
int mid = 0;
if (key <= arr[0]) {
return 0;
}
else if (key >= arr[n - 1]) {
return n - 1;
}
while (low <= high) {
mid = low + (high - low) / 2;
if (arr[mid] == key) {
return mid;
}
else if (key < arr[mid]) {
high = 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;
}
}
}
else {
low = 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;
}
public static int FindVirus(List< int > arr)
{
int i, index, n = arr.Count;
int sum = 0;
arr.Sort();
for (i = 0; i < n; i++) {
sum += arr[i];
}
while (arr.Count > 1) {
index = correctPOS(arr, arr.Count, sum / 2);
sum -= arr[index];
arr.RemoveAt(index);
}
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);
Console.Write(FindVirus(arr));
}
}
|
Javascript
<script>
function correctPOS(arr, n, key)
{
let low = 0, high = n - 1;
let mid = 0;
if (key <= arr[0]) {
return 0;
}
else if (key >= arr[n - 1]) {
return n - 1;
}
while (low <= high) {
mid = low + Math.floor((high - low) / 2);
if (arr[mid] == key) {
return mid;
}
else if (key < arr[mid]) {
high = 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;
}
}
}
else {
low = 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 FindVirus(arr)
{
let i, index, n = arr.length;
let sum = 0;
arr.sort((a,b) => b-a);
for (i = 0; i < n; i++) {
sum += arr[i];
}
while (arr.length > 1) {
index = correctPOS(arr, arr.length, Math.floor(sum / 2));
sum -= arr[index];
arr.pop(index);
}
return (arr[0]+1);
}
let arr = [];
arr.push(1);
arr.push(3);
arr.push(5);
arr.push(7);
document.write(FindVirus(arr));
</script>
|
Time Complexity: O(N2)
Auxiliary Space: O(1)
Last Updated :
01 Sep, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...