Given an array arr[] consisting of N integers, the task is to find the last remaining array element after removing every second element, starting from the first and last alternately.
Examples:
Input: arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Output: 8
Explanation: Elements in the list are: 1 2 3 4 5 6 7 8 9 10
Starting from first array element, removing every second element from arr[] = {1, 2. 3, 4, 5, 6, 7, 8, 9, 10} modifies arr[] to {2, 4, 6, 8, 10}.
Starting from last array element, removing every second element from arr[] = {2, 4, 6, 8, 10} modifies arr[] to {4, 8}.
Starting from first array element, removing every second element from arr[] = {4, 8} modifies arr[] to {8}.
Therefore, the last remaining element in the array is 8.Input: arr[] = {2, 3, 5, 6}
Output: 3
Naive Approach: The simplest approach to solve this problem is to remove every second element in the array starting from the first and last indices alternately until the size of the array reduces to 1. Print the last array element remaining after performing the given operations.
Time Complexity: O(N2)
Auxiliary Space: O(1)
Efficient Approach: The above approach can also be optimized by an observation in the below illustration for N = 20:
The following observations can be made from the above illustration:
- Every time N/2 numbers are eliminated.
- If the turn direction is from left to right (?), the first element of the sequence changes to (currentFirstElement + 2step – 1).
- If the turn direction is from right to left (?) and then remaining numbers in the list are odd, the first element of the sequence changes to (currentFirstElement + 2step – 1).
- After getting the final value of currentFirstElement from the above steps, print the value as the remaining element in the sequence.
Steps:
- Initialize a variable, say leftTurn, to check whether the element is to be deleted from the left or right.
- Initialize variables remainElements as N, steps as 1, and head as 1, to store the remaining element in the sequence, a number of steps performed, and the first element of the sequence.
- Iterate until remainElements is greater than 1:
- if the value of leftTurn is true, then update the head as (head + 2step – 1). Otherwise, if the remainElement is odd, then update the head as (head + 2step – 1).
- Update the value of remainElement as remainElement/2.
- Update the steps as 2 * steps.
- Toggle the leftTurn to remove elements from the right.
- After completing the above steps, print the value at the index (head – 1) as the remaining element.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to find the last element // remaining in the array after // performing the given operations void printLastElement( int arr[], int N)
{ // Checks if traversal is from
// left to right or vice versa
bool leftTurn = true ;
// Store the elements currently
// present in the array
int remainElements = N;
// Store the distance between 2
// consecutive array elements
int step = 1;
// Store the first element
// of the remaining array
int head = 1;
// Iterate while elements
// are greater than 1
while (remainElements > 1) {
// If left to right turn
if (leftTurn) {
// Update head
head = head + step;
}
// Otherwise, check if the
// remaining elements are odd
else {
// If true, update head
if (remainElements % 2 == 1)
head = head + step;
}
// Eliminate half of the array elements
remainElements = remainElements / 2;
// Double the steps after each turn
step = step * 2;
// Alter the turn
leftTurn = !leftTurn;
}
// Print the remaining element
cout << arr[head - 1];
} // Driver Code int main()
{ int arr[] = { 2, 3, 5, 6 };
int N = sizeof (arr) / sizeof (arr[0]);
printLastElement(arr, N);
return 0;
} |
// Java program for the above approach import java.lang.*;
class GFG{
// Function to find the last element // remaining in the array after // performing the given operations public static void printLastElement( int arr[], int N)
{ // Checks if traversal is from
// left to right or vice versa
boolean leftTurn = true ;
// Store the elements currently
// present in the array
int remainElements = N;
// Store the distance between 2
// consecutive array elements
int step = 1 ;
// Store the first element
// of the remaining array
int head = 1 ;
// Iterate while elements
// are greater than 1
while (remainElements > 1 )
{
// If left to right turn
if (leftTurn)
{
// Update head
head = head + step;
}
// Otherwise, check if the
// remaining elements are odd
else
{
// If true, update head
if (remainElements % 2 == 1 )
head = head + step;
}
// Eliminate half of the array elements
remainElements = remainElements / 2 ;
// Double the steps after each turn
step = step * 2 ;
// Alter the turn
leftTurn = !leftTurn;
}
// Print the remaining element
System.out.print( arr[head - 1 ]);
} // Driver code public static void main(String args[])
{ int [] arr = { 2 , 3 , 5 , 6 };
int N = arr.length;
printLastElement(arr, N);
} } // This code is contributed by SoumikMondal |
# Python3 program for the above approach # Function to find the last element # remaining in the array after # performing the given operations def printLastElement(arr, N):
# Checks if traversal is from
# left to right or vice versa
leftTurn = True
# Store the elements currently
# present in the array
remainElements = N
# Store the distance between 2
# consecutive array elements
step = 1
# Store the first element
# of the remaining array
head = 1
# Iterate while elements
# are greater than 1
while (remainElements > 1 ):
# If left to right turn
if (leftTurn):
# Update head
head = head + step
# Otherwise, check if the
# remaining elements are odd
else :
# If true, update head
if (remainElements % 2 = = 1 ):
head = head + step
# Eliminate half of the array elements
remainElements = remainElements / / 2
# Double the steps after each turn
step = step * 2
# Alter the turn
leftTurn = not leftTurn
# Print the remaining element
print (arr[head - 1 ])
# Driver Code if __name__ = = "__main__" :
arr = [ 2 , 3 , 5 , 6 ]
N = len (arr)
printLastElement(arr, N)
# This code is contributed by ukasp |
<script> // Javascript program for the above approach // Function to find the last element // remaining in the array after // performing the given operations function printLastElement(arr, N)
{ // Checks if traversal is from
// left to right or vice versa
var leftTurn = true ;
// Store the elements currently
// present in the array
var remainElements = N;
// Store the distance between 2
// consecutive array elements
var step = 1;
// Store the first element
// of the remaining array
var head = 1;
// Iterate while elements
// are greater than 1
while (remainElements > 1)
{
// If left to right turn
if (leftTurn)
{
// Update head
head = head + step;
}
// Otherwise, check if the
// remaining elements are odd
else
{
// If true, update head
if (remainElements % 2 == 1)
head = head + step;
}
// Eliminate half of the array elements
remainElements = remainElements / 2;
// Double the steps after each turn
step = step * 2;
// Alter the turn
leftTurn = !leftTurn;
}
// Print the remaining element
document.write(arr[head - 1]);
} // Driver code var arr = [ 2, 3, 5, 6 ];
var N = arr.length;
printLastElement(arr, N); // This code is contributed by Ankita saini </script> |
// C# program for the above approach using System;
public class GFG{
// Function to find the last element
// remaining in the array after // performing the given operations public static void printLastElement( int [] arr, int N)
{ // Checks if traversal is from
// left to right or vice versa
bool leftTurn = true ;
// Store the elements currently
// present in the array
int remainElements = N;
// Store the distance between 2
// consecutive array elements
int step = 1;
// Store the first element
// of the remaining array
int head = 1;
// Iterate while elements
// are greater than 1
while (remainElements > 1)
{
// If left to right turn
if (leftTurn)
{
// Update head
head = head + step;
}
// Otherwise, check if the
// remaining elements are odd
else
{
// If true, update head
if (remainElements % 2 == 1)
head = head + step;
}
// Eliminate half of the array elements
remainElements = remainElements / 2;
// Double the steps after each turn
step = step * 2;
// Alter the turn
leftTurn = !leftTurn;
}
// Print the remaining element
Console.Write( arr[head - 1]);
} // Driver code static public void Main (){
int [] arr = { 2, 3, 5, 6 };
int N = arr.Length;
printLastElement(arr, N);
}
} // This code is contributed by avanitrachhadiya2155 |
3
Time Complexity: O(log N)
Auxiliary Space: O(1)