Given two integers, n and k. Initially we have a sequence consisting of a single number 1. We need to consider series formed after n steps. In each step, we append the sequence to itself and insert the MEX(minimum excluded)(>0) value of the sequence in the middle. Perform (n-1) steps. Finally, find the value of the k-th index of the resulting sequence.
Example:
Input : n = 3, k = 2. Output: Initially, we have {1}, we have to perform 2 steps. 1st step : {1, 2, 1}, since MEX of {1} is 2. 2nd step: {1, 2, 1, 3, 1, 2, 1}, since MEX of {1, 2, 1} is 3. Value of 2nd Index = 2. Input : n = 4, k = 8. Output: Perform 3 steps. After second step, we have {1, 2, 1, 3, 1, 2, 1} 3rd step: {1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1}, since MEX = 4. Value of 8th index = 4.
A simple solution is to generate the series using given steps and store in an array. Finally, we return k-th element of the array.
An efficient solution is to use Binary Search. Observe that the middle element of our resulting sequence is n itself. Length of the sequence is 2n – 1, because lengths will be like (1, 3, 7, 15….2n -1). We use Binary search to solve this problem. As we know that the middle element of a sequence is the number of the step(from 1) performed on it.
In fact, every element in the sequence is a middle element at one or other step.
We start searching the element from step n and compare the middle index with ‘k’ if found we return n, else we decrease n by 1 and update our range of our search.
we repeat this step until the index is reached.
Implementation:
// CPP program to fin k-th element after append // and insert middle operations #include <bits/stdc++.h> using namespace std;
void findElement( int n, int k)
{ int ans = n; // Middle element of the sequence
int left = 1;
// length of the resulting sequence.
int right = pow (2, n) - 1;
while (1) {
int mid = (left + right) / 2;
if (k == mid) {
cout << ans << endl;
break ;
}
// Updating the middle element of next sequence
ans--;
// Moving to the left side of the middle element.
if (k < mid)
right = mid - 1;
// Moving to the right side of the middle element.
else
left = mid + 1;
}
} // Driver code int main()
{ int n = 4, k = 8;
findElement(n, k);
return 0;
} |
// Java program to fin k-th element after append // and insert middle operations class GFG
{ static void findElement( int n, int k)
{
// Middle element of the sequence
int ans = n;
int left = 1 ;
// length of the resulting sequence.
int right = ( int ) (Math.pow( 2 , n) - 1 );
while ( true )
{
int mid = (left + right) / 2 ;
if (k == mid)
{
System.out.println(ans);
break ;
}
// Updating the middle element
// of next sequence
ans--;
// Moving to the left side of
// the middle element.
if (k < mid)
{
right = mid - 1 ;
}
// Moving to the right side of
// the middle element.
else
{
left = mid + 1 ;
}
}
}
// Driver code
public static void main(String[] args)
{
int n = 4 , k = 8 ;
findElement(n, k);
}
} // This code has been contributed by 29AjayKumar |
# Python3 code to find k-th element after append # and insert middle operations import math
def findElement(n , k):
ans = n # Middle element of the sequence
left = 1
# length of the resulting sequence.
right = math. pow ( 2 , n) - 1
while 1 :
mid = int ((left + right) / 2 )
if k = = mid:
print (ans)
break
# Updating the middle element of next sequence
ans - = 1
# Moving to the left side of the middle element.
if k < mid:
right = mid - 1
# Moving to the right side of the middle element.
else :
left = mid + 1
# Driver code n = 4
k = 8
findElement(n, k) # This code is contributed by "Sharad_Bhardwaj". |
// C# program to fin k-th element after append // and insert middle operations using System;
class GFG
{ static void findElement( int n, int k)
{
// Middle element of the sequence
int ans = n;
int left = 1;
// length of the resulting sequence.
int right = ( int ) (Math.Pow(2, n) - 1);
while ( true )
{
int mid = (left + right) / 2;
if (k == mid)
{
Console.WriteLine(ans);
break ;
}
// Updating the middle element
// of next sequence
ans--;
// Moving to the left side of
// the middle element.
if (k < mid)
{
right = mid - 1;
}
// Moving to the right side of
// the middle element.
else
{
left = mid + 1;
}
}
}
// Driver code
public static void Main()
{
int n = 4, k = 8;
findElement(n, k);
}
} /* This code contributed by PrinciRaj1992 */ |
<?php // PHP program to fin k-th element // after append and insert middle // operations function findElement( $n , $k )
{ // Middle element of the sequence
$ans = $n ;
$left = 1;
// length of the resulting sequence.
$right = pow(2, $n ) - 1;
while (1)
{
$mid = ( $left + $right ) / 2;
if ( $k == $mid )
{
echo $ans , "\n" ;
break ;
}
// Updating the middle element
// of next sequence
$ans --;
// Moving to the left side of
// the middle element.
if ( $k < $id )
$right = $mid - 1;
// Moving to the right side
// of the middle element.
else
$left = $mid + 1;
}
} // Driver code
$n = 4;
$k = 8;
findElement( $n , $k );
// This code is contributed by aj_36 ?> |
<script> // JavaScript program to fin k-th element after append // and insert middle operations function findElement(n, k)
{
// Middle element of the sequence
let ans = n;
let left = 1;
// length of the resulting sequence.
let right = (Math.pow(2, n) - 1);
while ( true )
{
let mid = (left + right) / 2;
if (k == mid)
{
document.write(ans);
break ;
}
// Updating the middle element
// of next sequence
ans--;
// Moving to the left side of
// the middle element.
if (k < mid)
{
right = mid - 1;
}
// Moving to the right side of
// the middle element.
else
{
left = mid + 1;
}
}
}
// Driver code let n = 4, k = 8;
findElement(n, k);
// This code is contributed by code_hunt.
</script> |
Output:
4
Time Complexity: O(log n)