Giver an array arr[] consisting of N integers, the task is to perform right shift operations on array elements to convert the given array into a bitonic array.
Examples:
Input: arr[] = {7, 3, 4, 5, 3}
Output: 56 96 128 80 48
Explanation:
Perform the operation on the array elements as:
- 7 ? 00000111 ? 3 right shifts ? 00111000 ? 56
- 3 ? 00000011 ? 5 right shifts ? 01100000 ? 96
- 4 ? 00000100 ? 5 right shifts ? 10000000 ? 128
- 5 ? 00000101 ? 4 right shifts ? 01010000 ? 80
- 3 ? 00000011 ? 4 right shifts ? 00110000 ? 48
After the above operations the modified array is {56, 96, 128, 80, 48}, which is Bitonic array.
Input: arr[] = {255, 243, 23, 141, 46}
Output: -1
Approach: Follow the given steps to solve the problem
- Maximize the middle element of the array i.e., arr[N / 2], using right shift operations.
- Traverse the given array arr[], convert the first half of the array in ascending by performing right shift operations on the array element(if required).
- Traverse the given array arr[], convert the second half of the array in descending order via right shift operations on the array element(if required).
- After completing the above steps, check if the array is bitonic or not. Then print the array arr[] as the resultant array.
- Otherwise, print “-1”.
Below is the implementation of the above approach:
// C++ program for the above approach #include <iostream> #include <vector> #include <algorithm> #include <cmath> using namespace std;
// Function to check if an // array arr[] is Bitonic or not bool isPeak(vector< long long > arr) {
// Traverse the first half of arr[]
for ( int i = arr.size() / 2; i < arr.size() - 1; i++) {
if (arr[i] < arr[i + 1]) {
return false ;
}
}
// Traverse the second half of arr[]
for ( int i = 0; i < arr.size() / 2; i++) {
if (arr[i] > arr[i + 1]) {
return false ;
}
}
// Return true if arr[] is bitonic
return true ;
} // Function to maximize the value of N // by performing right shift operations long long maximize( long long n) {
long long Ele = n;
long long ans = n;
for ( int idx = 0; idx < 7; idx++) {
// Right shift by 1
if (Ele & 1) {
Ele >>= 1;
Ele += pow (2, 32);
} else {
Ele >>= 1;
}
// Update the value of ans
ans = max(ans, Ele);
}
return ans;
} // Function to arrange array in descending // order by right shift operations vector< long long > makeDec(vector< long long > arr) {
// Maximise the array arr[0]
long long prev = maximize(arr[0]);
arr[0] = prev;
// Iterate through array arr[]
for ( int i = 1; i < arr.size(); i++) {
long long optEle = arr[i];
// Flag to find the first
// element less than prev
bool flag = true ;
// Update Ele as arr[i]
long long Ele = arr[i];
for ( int idx = 0; idx < 7; idx++) {
// Right shift by 1
if (Ele & 1) {
Ele >>= 1;
Ele += pow (2, 32);
} else {
Ele >>= 1;
}
if (Ele < prev && flag) {
// Update the optEle
optEle = Ele;
// Unset the flag
flag = false ;
}
if (Ele < prev) {
// Update the optEle
optEle = max(optEle, Ele);
}
}
// Update the array arr[i]
arr[i] = optEle;
// Update the value of prev
prev = arr[i];
}
// Return the array
return arr;
} // Function to find the peak // element of the array arr[] vector< long long > makePeak(vector< long long > arr) {
// First half of the array
vector< long long > first(arr.begin(), arr.begin() + arr.size() / 2 + 1);
reverse(first.begin(), first.end());
// Second half of the array
vector< long long > second(arr.begin() + arr.size() / 2, arr.end());
// Merg both halves
vector< long long > ans = makeDec(first);
reverse(ans.begin(), ans.end());
vector< long long > secondPart = makeDec(second);
secondPart.erase(secondPart.begin());
ans.insert(ans.end(), secondPart.begin(), secondPart.end());
// Function Call
if (isPeak(ans)) {
return ans;
}
vector< long long > emptyVec;
return emptyVec;
} // Driver Code int main() {
// Given array
vector< long long > arr = {7, 3, 4, 5, 3};
// Function Call
vector< long long > result = makePeak(arr);
if (result.size() > 0) {
for ( int i = 0; i < result.size(); i++) {
cout << result[i] << " " ;
}
} else {
cout << "No peak found" ;
}
return 0;
} // This code is contributed by Prajwal Kandekar |
// Java program for the above approach import java.util.*;
import java.math.*;
class GFG {
// Function to check if an
// array arr[] is Bitonic or not
static boolean isPeak(Vector <Long> arr) {
// Traverse the first half of arr[]
for ( int i = arr.size() / 2 ; i < arr.size() - 1 ; i++) {
if (arr.get(i) < arr.get(i + 1 )) {
return false ;
}
}
// Traverse the second half of arr[]
for ( int i = 0 ; i < arr.size() / 2 ; i++) {
if (arr.get(i) > arr.get(i + 1 )) {
return false ;
}
}
// Return true if arr[] is bitonic
return true ;
}
// Function to maximize the value of N
// by performing right shift operations
static long maximize( long n) {
long Ele = n;
long ans = n;
for ( int idx = 0 ; idx < 7 ; idx++) {
// Right shift by 1
if ((Ele & 1 ) == 1 ) {
Ele >>= 1 ;
Ele += Math.pow( 2 , 32 );
} else {
Ele >>= 1 ;
}
// Update the value of ans
ans = Math.max(ans, Ele);
}
return ans;
}
// Function to arrange array in descending
// order by right shift operations
static Vector <Long> makeDec(Vector <Long> arr) {
// Maximise the array arr[0]
long prev = maximize(arr.get( 0 ));
arr.set( 0 , prev);
// Iterate through array arr[]
for ( int i = 1 ; i < arr.size(); i++) {
long optEle = arr.get(i);
// Flag to find the first
// element less than prev
boolean flag = true ;
// Update Ele as arr[i]
long Ele = arr.get(i);
for ( int idx = 0 ; idx < 7 ; idx++) {
// Right shift by 1
if ((Ele & 1 ) == 1 ) {
Ele >>= 1 ;
Ele += Math.pow( 2 , 32 );
} else {
Ele >>= 1 ;
}
if (Ele < prev && flag) {
// Update the optEle
optEle = Ele;
// Unset the flag
flag = false ;
}
if (Ele < prev) {
// Update the optEle
optEle = Math.max(optEle, Ele);
}
}
// Update the array arr[i]
arr.set(i, optEle);
// Update the value of prev
prev = arr.get(i);
}
// Return the array
return arr;
}
// Function to find the peak
// element of the array arr[]
static Vector <Long> makePeak(Vector <Long> arr) {
// First half of the array
Vector <Long> first = new Vector<Long>
(arr.subList( 0 , arr.size() / 2 + 1 ));
Collections.reverse(first);
// Second half of the array
Vector <Long> second = new Vector<Long>
(arr.subList(arr.size() / 2 , arr.size()));
// Merg both halves
Vector <Long> ans = makeDec(first);
Collections.reverse(ans);
Vector <Long> secondPart = makeDec(second);
secondPart.remove( 0 );
ans.addAll(secondPart);
// Function Call
if (isPeak(ans)) {
return ans;
}
Vector <Long> emptyVec = new Vector<Long>();
return emptyVec;
}
// Driver Code
public static void main(String[] args) {
// Given array
Vector <Long> arr = new Vector<Long>
(Arrays.asList(7L, 3L, 4L, 5L, 3L));
// Function Call
Vector <Long> result = makePeak(arr);
if (result.size() > 0 ) {
for ( int i = 0 ; i < result.size(); i++) {
System.out.print(result.get(i) + " " );
}
} else {
System.out.print( "No peak found" );
}
}
} |
# Python program for the above approach # Function to check if an # array arr[] is Bitonic or not def isPeak(arr):
# Traverse the first half of arr[]
for i in range ( len (arr) / / 2 , len (arr) - 1 ):
if arr[i] < arr[i + 1 ]:
return False
# Traverse the second half of arr[]
for i in range ( len (arr) / / 2 ):
if arr[i] > arr[i + 1 ]:
return False
# Return true if arr[] is bitonic
return True
# Function to maximize the value of N # by performing right shift operations def maximize(n):
Ele = n
ans = n
for idx in range ( 7 ):
# Right shift by 1
if Ele & 1 :
Ele >> = 1
Ele + = 2 * * 32
else :
Ele >> = 1
# Update the value of ans
ans = max (ans, Ele)
return ans
# Function to arrange array in descending # order by right shift operations def makeDec(arr):
# Maximise the array arr[0]
prev = maximize(arr[ 0 ])
arr[ 0 ] = prev
# Iterate through array arr[]
for i in range ( 1 , len (arr)):
optEle = arr[i]
# Flag to find the first
# element less than prev
flag = True
# Update Ele as arr[i]
Ele = arr[i]
for idx in range ( 7 ):
# Right shift by 1
if Ele & 1 :
Ele >> = 1
Ele + = 2 * * 32
else :
Ele >> = 1
if Ele < prev and flag:
# Update the optEle
optEle = Ele
# Unset the flag
flag = False
if Ele < prev:
# Update the optEle
optEle = max (optEle, Ele)
# Update the array arr[i]
arr[i] = optEle
# Update the value of prev
prev = arr[i]
# Return the array
return arr
# Function to find the peak # element of the array arr[] def makePeak(arr):
# First half of the array
first = arr[: len (arr) / / 2 + 1 ]
first.reverse()
# Second half of the array
second = arr[ len (arr) / / 2 :]
# Merg both halves
ans = makeDec(first)[:: - 1 ] + makeDec(second)[ 1 :]
# Function Call
if isPeak(ans):
return ans
return - 1
# Driver Code # Given array arr = [ 7 , 3 , 4 , 5 , 3 ]
# Function Call print (makePeak(arr))
|
// C# program for the above approach using System;
using System.Collections.Generic;
using System.Linq;
public class Program {
// Function to check if an
// array arr[] is Bitonic or not
static bool IsPeak(List< long > arr)
{
// Traverse the first half of arr[]
for ( int i = arr.Count / 2; i < arr.Count - 1;
i++) {
if (arr[i] < arr[i + 1]) {
return false ;
}
}
// Traverse the second half of arr[]
for ( int i = 0; i < arr.Count / 2; i++) {
if (arr[i] > arr[i + 1]) {
return false ;
}
}
// Return true if arr[] is bitonic
return true ;
}
// Function to maximize the value of N
// by performing right shift operations
static long Maximize( long n)
{
long ele = n;
long ans = n;
for ( int idx = 0; idx < 7; idx++) {
// Right shift by 1
if ((ele & 1) == 1) {
ele >>= 1;
ele += ( long )Math.Pow(2, 32);
}
else {
ele >>= 1;
}
// Update the value of ans
ans = Math.Max(ans, ele);
}
return ans;
}
// Function to arrange array in descending
// order by right shift operations
static List< long > MakeDec(List< long > arr)
{
// Maximise the array arr[0]
long prev = Maximize(arr[0]);
arr[0] = prev;
// Iterate through array arr[]
for ( int i = 1; i < arr.Count; i++) {
long optEle = arr[i];
// Flag to find the first
// element less than prev
bool flag = true ;
// Update Ele as arr[i]
long ele = arr[i];
for ( int idx = 0; idx < 7; idx++) {
// Right shift by 1
if ((ele & 1) == 1) {
ele >>= 1;
ele += ( long )Math.Pow(2, 32);
}
else {
ele >>= 1;
}
if (ele < prev && flag) {
// Update the optEle
optEle = ele;
// Unset the flag
flag = false ;
}
if (ele < prev) {
// Update the optEle
optEle = Math.Max(optEle, ele);
}
}
// Update the array arr[i]
arr[i] = optEle;
// Update the value of prev
prev = arr[i];
}
// Return the array
return arr;
}
// Function to find the peak
// element of the array arr[]
static List< long > MakePeak(List< long > arr)
{
// First half of the array
List< long > first
= arr.GetRange(0, arr.Count / 2 + 1);
first.Reverse();
// Second half of the array
List< long > second = arr.GetRange(
arr.Count / 2, arr.Count - arr.Count / 2);
// Merg both halves
List< long > ans = MakeDec(first);
ans.Reverse();
List< long > secondPart = MakeDec(second);
secondPart.RemoveAt(0);
ans.AddRange(secondPart);
// Function Call
if (IsPeak(ans)) {
return ans;
}
return new List< long >();
}
// Driver Code
public static void Main()
{
// Given array
List< long > arr = new List< long >() { 7, 3, 4, 5, 3 };
// Function Call
List< long > result = MakePeak(arr);
if (result.Count > 0) {
Console.WriteLine( string .Join( " " , result));
}
else {
Console.WriteLine( "No peak found" );
}
}
} // This code is contributed by Prajwal Kandekar |
[1879048192, 3221225472, 4294967296, 2684354560, 1610612736]
Time Complexity: O(N * log(M)), where M is the maximum element of arr[] .
Auxiliary Space: O(N) as it is using extra space for list first and second to copy the array