Find the last remaining element after repeated removal of odd and even indexed elements alternately - GeeksforGeeks

31 May, 2021
Given a positive integer N, the task is to print the last remaining element from a sequence [1, N] after repeatedly performing the following operations in the given order alternately:
Remove all the odd-indexed elements from the sequence.Remove all the even-indexed elements from the sequence.
Remove all the odd-indexed elements from the sequence.
Remove all the even-indexed elements from the sequence.
Examples:
Input: N = 9Output: 6Explanation: Sequence = {1, 2, 3, 4, 5, 6, 7, 8, 9}Step 1: Removing odd-indexed elements modifies sequence to {2, 4, 6, 8}Step 2: Removing even-indexed elements modifies sequence to {2, 6}Step 3: Removing odd-indexed elements modifies sequence to {6}Therefore, the last remaining element is 6.
Input: N = 5Output: 2Explanation: Sequence = {1, 2, 3, 4, 5}Step 1: Removing odd-indexed elements modifies sequence to {2, 4}Step 2: Removing even-indexed elements modifies sequence to {2}Therefore, the last remaining element is 2.
Naive Approach: The simplest approach is to store all the elements from 1 to N sequentially in an array. For every operation, remove elements from the array and shift the remaining elements towards the left. After reducing the array to a single element, print that remaining element as the required answer. 
Time Complexity: O(N2*log N)Auxiliary Space: O(N)
Efficient Approach: The above approach can be optimized using Dynamic Programming. The recurrence relation is as follows:
 
where, i is in the range [1, N]dp[i] stores the answer when the array elements are from 1 to i.
Follow the steps below to solve the problem:
Initialize an array dp[] where dp[i] stores the remaining element or the sequence [1, i].For the base condition of i = 1, print 1 as the required answer.Calculate the value of dp[N] using the aforementioned recurrence relation and use the already computed subproblems to avoid recomputation of overlapping subproblems.After completing the above steps, print the value of dp[N] as the result.
Initialize an array dp[] where dp[i] stores the remaining element or the sequence [1, i].
For the base condition of i = 1, print 1 as the required answer.
Calculate the value of dp[N] using the aforementioned recurrence relation and use the already computed subproblems to avoid recomputation of overlapping subproblems.
After completing the above steps, print the value of dp[N] as the result.
Below is the implementation of the above approach:
C++14
Java
Python3
C#
Javascript
// C++14 program for the above approach#include <bits/stdc++.h>using namespace std; // Function to calculate the last// remaining element from the sequenceint lastRemaining(int n, map<int, int> &dp){         // If dp[n] is already calculated    if (dp.find(n) != dp.end())        return dp[n];     // Base Case:    if (n == 1)        return 1;         // Recursive call    else        dp[n] = 2 * (1 + n / 2 -           lastRemaining(n / 2, dp));     // Return the value of dp[n]    return dp[n];} // Driver Codeint main(){         // Given N    int N = 5;         // Stores the    map<int, int> dp;         // Function call    cout << lastRemaining(N, dp);         return 0;} // This code is contributed by mohit kumar 29
// Java program for// the above approachimport java.util.*;class GFG{ // Function to calculate the last// remaining element from the sequencestatic int lastRemaining(int n, HashMap<Integer,                                        Integer> dp){  // If dp[n] is already calculated  if (dp.containsKey(n))    return dp.get(n);   // Base Case:  if (n == 1)    return 1;   // Recursive call  else    dp.put(n, 2 * (1 + n / 2 -           lastRemaining(n / 2, dp)));   // Return the value of dp[n]  return dp.get(n);} // Driver Codepublic static void main(String[] args){     // Given N  int N = 5;   // Stores the  HashMap<Integer,          Integer> dp = new HashMap<Integer,                                    Integer>();   // Function call  System.out.print(lastRemaining(N, dp));}} // This code is contributed by Princi Singh
# Python program for the above approach # Function to calculate the last# remaining element from the sequencedef lastRemaining(n, dp):   # If dp[n] is already calculated    if n in dp:        return dp[n]     # Base Case:    if n == 1:        return 1     # Recursive Call    else:        dp[n] = 2*(1 + n//2        - lastRemaining(n//2, dp))     # Return the value of dp[n]    return dp[n]  # Driver Code # Given NN = 5 # Stores thedp = {} # Function Callprint(lastRemaining(N, dp))
// C# program for the above approachusing System;using System.Collections.Generic; class GFG{ // Function to calculate the last// remaining element from the sequencestatic int lastRemaining(int n, Dictionary<int,                                           int> dp){         // If dp[n] is already calculated    if (dp.ContainsKey(n))        return dp[n];         // Base Case:    if (n == 1)        return 1;         // Recursive call    else        dp.Add(n, 2 * (1 + n / 2 -             lastRemaining(n / 2, dp)));         // Return the value of dp[n]    return dp[n];} // Driver Codepublic static void Main(String[] args){          // Given N    int N = 5;         // Stores the    Dictionary<int,               int> dp = new Dictionary<int,                                        int>();         // Function call    Console.Write(lastRemaining(N, dp));}} // This code is contributed by Princi Singh
<script>      // JavaScript program for the above approach      // Function to calculate the last      // remaining element from the sequence      function lastRemaining(n, dp) {        // If dp[n] is already calculated        if (dp.hasOwnProperty(n))            return dp[n];         // Base Case:        if (n === 1)            return 1;        // Recursive call        else          dp[n] =            2 * (1 + parseInt(n / 2) -            lastRemaining(parseInt(n / 2), dp));         // Return the value of dp[n]        return dp[n];      }       // Driver Code      // Given N      var N = 5;       // Stores the      var dp = {};       // Function call      document.write(lastRemaining(N, dp));</script>
2
 
Time Complexity: O(N)Auxiliary Space: O(N)
mohit kumar 29
princi singh
rdtank
array-rearrange
Memoization
Arrays
Dynamic Programming
Mathematical
Recursion
Arrays
Dynamic Programming
Mathematical
Recursion
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Introduction to Arrays
Multidimensional Arrays in Java
Linear Search
Linked List vs Array
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
0-1 Knapsack Problem | DP-10
Program for Fibonacci numbers
Longest Common Subsequence | DP-4
Bellman–Ford Algorithm | DP-23
Floyd Warshall Algorithm | DP-16