Maximize difference between odd and even indexed array elements by swapping unequal adjacent bits in their binary representations
Last Updated :
19 May, 2021
Given an array arr[] consisting of N positive integers, the task is to find the maximum absolute difference between the sum of the array elements placed at even and odd indices of the array by swapping unequal adjacent bits of in the binary representation of any array element any number of times.
Examples:
Input: arr[] = {5, 7, 3, 1, 8}
Output: 9
Explanation:
arr[0] = (5)10 = (101)2. Left shift bits to make arr[0] = (110)2 = (6)10.
Therefore, the array arr[] modifies to {5, 7, 3, 1, 8}.
Therefore, the maximum absolute difference = (6 + 3 + 8) – (7 + 1) = 9.
Input: arr[] = {54, 32, 11, 23}
Output: 58
Explanation:
Modify arr[0] to 60 by left shifting the last two set bits of arr[0] (= 54). Therefore, the array arr[] modifies to {60, 32, 11, 23}.
Modify arr[1] to 1 by right shifting all the set bits of arr[1] (= 32). Therefore, the array arr[] modifies to {60, 1, 11, 23}
Modify arr[2] to 14 by left shifting the last three set bits of arr[2] (= 11). Therefore, the array arr[] modifies to {60, 1, 14, 23}.
Modify arr[3] to 15 by right shifting all the set bits of arr[3] (= 23). Therefore, the array arr[] modifies to {60, 1, 14, 15}.
Therefore, the maximum absolute difference = (60 + 14) – (15 + 1) = 58.
Approach: The idea is to use the observation that any set bit can be moved to any other position. Follow the steps below to solve the problem:
- Define a function, say maximize(), to maximize a number by shifting two unequal adjacent bits.
- Define a function, say minimize(), to minimize a number by shifting two unequal adjacent bits.
- Perform the following operations:
- Initialize a variable, say ans, to store the minimized value.
- To minimize a number, shift all the set bits to the right position and all the unset bits to the left position.
- Traverse over the range [0, count of set bit – 1] and update ans as ans | 1. If i not equal to the count of set bits, then left shift ans by 1.
- Return the value of ans.
- First, find the difference obtained by maximizing the element placed at even indices and minimizing the elements placed at odd indices. Store it in a variable, say caseOne.
- Now, find the difference obtained by minimizing the element placed at even indices and maximizing the elements placed at odd indices. Store it in a variable, say caseTwo.
- After completing the above steps, print the maximum of caseOne and CaseTwo.
Below is the implementation of the above approach:
C++
#include<bits/stdc++.h>
using namespace std;
int countBit( int n){
return int (log2(n))+1;
}
int countSetBit( int n){
int ans = 0;
while (n > 0){
ans += (n & 1);
n >>= 1;
}
return ans;
}
int maximize( int n){
int bits = countBit(n);
int setBits = countSetBit(n);
int ans = 0;
for ( int i = 0; i < bits; i++){
if (i < setBits)
ans |= 1;
if (i != setBits - 1)
ans <<= 1;
}
return ans;
}
int minimize( int n){
int setBits = countSetBit(n);
int ans = 0;
for ( int i = 0; i < setBits; i++){
ans |= 1;
if (i != setBits - 1)
ans <<= 1;
}
return ans;
}
int maxDiff(vector< int > arr){
int caseOne = 0;
int SumOfOdd = 0;
int SumOfeven = 0;
for ( int i = 0; i < arr.size(); i++){
if (i % 2)
SumOfOdd += minimize(arr[i]);
else
SumOfeven += maximize(arr[i]);
}
caseOne = abs (SumOfOdd - SumOfeven);
int caseTwo = 0;
SumOfOdd = 0;
SumOfeven = 0;
for ( int i = 0; i < arr.size(); i++)
{
if (i % 2)
SumOfOdd += maximize(arr[i]);
else
SumOfeven += minimize(arr[i]);
}
caseTwo = abs (SumOfOdd - SumOfeven);
return max(caseOne, caseTwo);
}
int main()
{
vector< int > arr{54, 32, 11, 23};
cout<<maxDiff(arr);
}
|
Java
import java.util.*;
class GFG{
static int countBit( int n){
return ( int )((Math.log(n) / Math.log( 2 ))+ 1 );
}
static int countSetBit( int n){
int ans = 0 ;
while (n > 0 ){
ans += (n & 1 );
n >>= 1 ;
}
return ans;
}
static int maximize( int n){
int bits = countBit(n);
int setBits = countSetBit(n);
int ans = 0 ;
for ( int i = 0 ; i < bits; i++){
if (i < setBits)
ans |= 1 ;
if (i != setBits - 1 )
ans <<= 1 ;
}
return ans;
}
static int minimize( int n){
int setBits = countSetBit(n);
int ans = 0 ;
for ( int i = 0 ; i < setBits; i++){
ans |= 1 ;
if (i != setBits - 1 )
ans <<= 1 ;
}
return ans;
}
static int maxDiff( int [] arr){
int caseOne = 0 ;
int SumOfOdd = 0 ;
int SumOfeven = 0 ;
for ( int i = 0 ; i < arr.length; i++){
if ((i % 2 ) != 0 )
SumOfOdd += minimize(arr[i]);
else
SumOfeven += maximize(arr[i]);
}
caseOne = Math.abs(SumOfOdd - SumOfeven);
int caseTwo = 0 ;
SumOfOdd = 0 ;
SumOfeven = 0 ;
for ( int i = 0 ; i < arr.length; i++)
{
if ((i % 2 ) != 0 )
SumOfOdd += maximize(arr[i]);
else
SumOfeven += minimize(arr[i]);
}
caseTwo = Math.abs(SumOfOdd - SumOfeven);
return Math.max(caseOne, caseTwo);
}
public static void main(String[] args)
{
int [] arr = { 54 , 32 , 11 , 23 };
System.out.println(maxDiff(arr));
}
}
|
Python3
import math
def countBit(n):
return int (math.log(n, 2 )) + 1
def countSetBit(n):
ans = 0
while n:
ans + = n & 1
n >> = 1
return ans
def maximize(n):
bits = countBit(n)
setBits = countSetBit(n)
ans = 0
for i in range (bits):
if i < setBits:
ans | = 1
if i ! = setBits - 1 :
ans << = 1
return ans
def minimize(n):
setBits = countSetBit(n)
ans = 0
for i in range (setBits):
ans | = 1
if i ! = setBits - 1 :
ans << = 1
return ans
def maxDiff(arr):
caseOne = 0
SumOfOdd = 0
SumOfeven = 0
for i in range ( len (arr)):
if i % 2 :
SumOfOdd + = minimize(arr[i])
else :
SumOfeven + = maximize(arr[i])
caseOne = abs (SumOfOdd - SumOfeven)
caseTwo = 0
SumOfOdd = 0
SumOfeven = 0
for i in range ( len (arr)):
if i % 2 :
SumOfOdd + = maximize(arr[i])
else :
SumOfeven + = minimize(arr[i])
caseTwo = abs (SumOfOdd - SumOfeven)
return max (caseOne, caseTwo)
arr = [ 54 , 32 , 11 , 23 ]
print (maxDiff(arr))
|
C#
using System;
class GFG{
static int countBit( int n){
return ( int )((Math.Log(n) / Math.Log(2))+1);
}
static int countSetBit( int n){
int ans = 0;
while (n > 0){
ans += (n & 1);
n >>= 1;
}
return ans;
}
static int maximize( int n){
int bits = countBit(n);
int setBits = countSetBit(n);
int ans = 0;
for ( int i = 0; i < bits; i++){
if (i < setBits)
ans |= 1;
if (i != setBits - 1)
ans <<= 1;
}
return ans;
}
static int minimize( int n){
int setBits = countSetBit(n);
int ans = 0;
for ( int i = 0; i < setBits; i++){
ans |= 1;
if (i != setBits - 1)
ans <<= 1;
}
return ans;
}
static int maxDiff( int [] arr){
int caseOne = 0;
int SumOfOdd = 0;
int SumOfeven = 0;
for ( int i = 0; i < arr.Length; i++){
if ((i % 2) != 0)
SumOfOdd += minimize(arr[i]);
else
SumOfeven += maximize(arr[i]);
}
caseOne = Math.Abs(SumOfOdd - SumOfeven);
int caseTwo = 0;
SumOfOdd = 0;
SumOfeven = 0;
for ( int i = 0; i < arr.Length; i++)
{
if ((i % 2) != 0)
SumOfOdd += maximize(arr[i]);
else
SumOfeven += minimize(arr[i]);
}
caseTwo = Math.Abs(SumOfOdd - SumOfeven);
return Math.Max(caseOne, caseTwo);
}
public static void Main( string [] args)
{
int [] arr = {54, 32, 11, 23};
Console.Write(maxDiff(arr));
}
}
|
Javascript
<script>
function countBit(n){
return parseInt(log2(n))+1;
}
function countSetBit(n){
let ans = 0;
while (n > 0){
ans += (n & 1);
n >>= 1;
}
return ans;
}
function maximize(n){
let bits = countBit(n);
let setBits = countSetBit(n);
let ans = 0;
for (let i = 0; i < bits; i++){
if (i < setBits)
ans |= 1;
if (i != setBits - 1)
ans <<= 1;
}
return ans;
}
function minimize(n){
let setBits = countSetBit(n);
let ans = 0;
for (let i = 0; i < setBits; i++){
ans |= 1;
if (i != setBits - 1)
ans <<= 1;
}
return ans;
}
function maxDiff(arr){
let caseOne = 0;
let SumOfOdd = 0;
let SumOfeven = 0;
for (let i = 0; i < arr.length; i++){
if (i % 2)
SumOfOdd += minimize(arr[i]);
else
SumOfeven += maximize(arr[i]);
}
caseOne = Math.abs(SumOfOdd - SumOfeven);
let caseTwo = 0;
SumOfOdd = 0;
SumOfeven = 0;
for (let i = 0; i < arr.length; i++)
{
if (i % 2)
SumOfOdd += maximize(arr[i]);
else
SumOfeven += minimize(arr[i]);
}
caseTwo = Math.abs(SumOfOdd - SumOfeven);
return Math.max(caseOne, caseTwo);
}
let arr = [54, 32, 11, 23];
document.write(maxDiff(arr));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...