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++ 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 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). |
# 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# 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 |
<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>
|
8
Time Complexity: O(N2)
Auxiliary Space: O(1)