Largest subset where absolute difference of any two element is a power of 2

Given an array arr[] of distinct elements -109 ≤ ai ≤ 109. The task is to find the largest sub-set from the given array such that the absolute difference between any two numbers in the sub-set is a positive power of two. If it is not possible to make such sub-set then print -1.

Examples:

Input: arr[] = {3, 4, 5, 6, 7}
Output: 3 5 7
|3 – 5| = 21, |5 – 7| = 21 and |3 – 7| = 22.



Input: arr[] = {2, 5, 8}
Output: -1

Approach: Let’s prove that the size of the sub-set will not be > 3. Suppose a, b, c and d are four elements from a sub-set and a < b < c < d.
Let abs(a – b) = 2k and abs(b – c) = 2l then abs(a – c) = abs(a – b) + abs(b – c) = 2k + 2l = 2m. It means that k = l. Conditions must hold for the triple (b, c, d) too. Now it is easy to see that if abs(a – b) = abs(b – c) = abs(c – d) = 2k then abs(a – d) = abs(a – b) * 3 which is not a power of two. So the size of the sub-set will never be greater than 3.

  • Let’s check if the answer is 3. Iterate over the given array for middle elements of the sub-set and for powers of two from 1 to 30 inclusively. Let xi be the middle element of the sub-set and j the current power of two. Then if there are elements xi-2j and xi+2j in the array then the answer is 3.
  • Else check if the answer is 2. repeat the previous step but here one can get either left point xi-2j or xi+2j.
  • If the answer is neither 2 nor 3 then print -1.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// CPP program to find sub-set with
// maximum possible size
#include <bits/stdc++.h>
using namespace std;
  
// Function to find sub-set with
// maximum possible size
void PowerOfTwo(vector<int> x, int n)
{
    // Sort the given array
    sort(x.begin(), x.end());
  
    // To store required sub-set
    vector<int> res;
  
    for (int i = 0; i < n; ++i) {
  
        // Iterate for all powers of two
        for (int j = 1; j < 31; ++j) {
  
            // Left number
            int lx = x[i] - (1 << j);
  
            // Right number
            int rx = x[i] + (1 << j);
  
            // Predefined binary search in c++
            bool isl = binary_search(x.begin(), x.end(), lx);
            bool isr = binary_search(x.begin(), x.end(), rx);
  
            // If possible to get sub-set of size 3
            if (isl && isr && int(res.size()) < 3)
                res = { lx, x[i], rx };
  
            // If possible to get sub-set of size 2
            if (isl && int(res.size()) < 2)
                res = { lx, x[i] };
  
            // If possible to get sub-set of size 2
            if (isr && int(res.size()) < 2)
                res = { x[i], rx };
        }
    }
  
    // If not possible to get sub-set
    if (!res.size()) {
        cout << -1;
        return;
    }
  
    // Print the sub-set
    for (auto it : res)
        cout << it << " ";
}
  
// Driver Code
int main()
{
  
    vector<int> a = { 3, 4, 5, 6, 7 };
  
    int n = a.size();
    PowerOfTwo(a, n);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find sub-set with
// maximum possible size
import java.util.*;
  
class GFG
{
      
// Function to find sub-set with
// maximum possible size
static void PowerOfTwo(int []x, int n)
{
    // Sort the given array
    Arrays.sort(x);
  
    // To store required sub-set
    ArrayList<Integer> res = new ArrayList<Integer>();
  
    for (int i = 0; i < n; ++i) 
    {
  
        // Iterate for all powers of two
        for (int j = 1; j < 31; ++j) 
        {
  
            // Left number
            int lx = x[i] - (1 << j);
  
            // Right number
            int rx = x[i] + (1 << j);
  
            // Predefined binary search in Java
            boolean isl = Arrays.binarySearch(x,lx) <
                                    0 ? false : true;
            boolean isr = Arrays.binarySearch(x,rx) < 
                                    0 ? false : true;
  
            // If possible to get sub-set of size 3
            if (isl && isr && res.size() < 3)
            {
                res.clear();
                res.add(lx);
                res.add(x[i]);
                res.add(rx);
            }
  
            // If possible to get sub-set of size 2
            if (isl && res.size() < 2)
            {
                res.clear();
                res.add(lx);
                res.add(x[i]);
            }
            // If possible to get sub-set of size 2
            if (isr && res.size() < 2)
            {
                res.clear();
                res.add(x[i]);
                res.add(rx);
            }
        }
    }
  
    // If not possible to get sub-set
    if (res.size() == 0)
    {
        System.out.println("-1");
        return;
    }
  
    // Print the sub-set
    for (int i = 0; i < res.size(); i++)
        System.out.print(res.get(i) + " ");
}
  
// Driver Code
public static void main (String[] args) 
{
    int[] a = {3, 4, 5, 6, 7};
    int n = a.length;
    PowerOfTwo(a, n);
}
}
  
// This code is Contributed by chandan_jnu

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to find sub-set with 
# maximum possible size 
  
# Function to find sub-set with 
# maximum possible size 
def PowerOfTwo(x, n) : 
      
    # Sort the given array 
    x.sort()
  
    # To store required sub-set 
    res = [] 
  
    for i in range(n) : 
  
        # Iterate for all powers of two 
        for j in range(1, 31) :
              
            # Left number 
            lx = x[i] - (1 << j)
  
            # Right number 
            rx = x[i] + (1 << j) 
  
            if lx in x :
                isl = True
            else :
                isl = False
              
            if rx in x :
                isr = True
            else :
                isr = False
              
            # If possible to get sub-set of size 3 
            if (isl and isr and len(res) < 3) :
                res = [ lx, x[i], rx ] 
  
            # If possible to get sub-set of size 2 
            if (isl and len(res) < 2) :
                res = [ lx, x[i] ] 
  
            # If possible to get sub-set of size 2 
            if (isr and len(res) < 2) :
                res = [ x[i], rx ]
  
    # If not possible to get sub-set 
    if (not len(res)) :
        print(-1
        return
      
    # Print the sub-set 
    for it in res :
        print(it, end = " "
  
# Driver Code 
if __name__ == "__main__" :
  
    a = [ 3, 4, 5, 6, 7
  
    n = len(a)
    PowerOfTwo(a, n) 
  
# This code is contributed by Ryuga

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find sub-set with
// maximum possible size
using System;
using System.Collections;
  
class GFG
{
      
// Function to find sub-set with
// maximum possible size
static void PowerOfTwo(int[] x, int n)
{
    // Sort the given array
    Array.Sort(x);
  
    // To store required sub-set
    ArrayList res = new ArrayList();
  
    for (int i = 0; i < n; ++i) 
    {
  
        // Iterate for all powers of two
        for (int j = 1; j < 31; ++j) 
        {
  
            // Left number
            int lx = x[i] - (1 << j);
  
            // Right number
            int rx = x[i] + (1 << j);
  
            // Predefined binary search in C#
            bool isl = Array.IndexOf(x, lx) < 0? false : true;
            bool isr = Array.IndexOf(x, rx) < 0? false : true;
  
            // If possible to get sub-set of size 3
            if (isl && isr && res.Count < 3)
            {
                res.Clear();
                res.Add(lx);
                res.Add(x[i]);
                res.Add(rx);
            }
  
            // If possible to get sub-set of size 2
            if (isl && res.Count < 2)
            {
                res.Clear();
                res.Add(lx);
                res.Add(x[i]);
            }
            // If possible to get sub-set of size 2
            if (isr && res.Count < 2)
            {
                res.Clear();
                res.Add(x[i]);
                res.Add(rx);
            }
        }
    }
  
    // If not possible to get sub-set
    if (res.Count == 0)
    {
        Console.Write("-1");
        return;
    }
  
    // Print the sub-set
    for (int i = 0; i < res.Count; i++)
        Console.Write(res[i] + " ");
}
  
// Driver Code
public static void Main() 
{
    int[] a = {3, 4, 5, 6, 7};
    int n = a.Length;
    PowerOfTwo(a, n);
}
}
  
// This code is Contributed by chandan_jnu

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP program to find sub-set with
// maximum possible size
  
// Function to find sub-set with
// maximum possible size
function PowerOfTwo($x, $n)
{
    // Sort the given array
    sort($x);
  
    // To store required sub-set
    $res = array();
  
    for ($i = 0; $i < $n; ++$i
    {
  
        // Iterate for all powers of two
        for ($j = 1; $j < 31; ++$j
        {
  
            // Left number
            $lx = $x[$i] - (1 << $j);
  
            // Right number
            $rx = $x[$i] + (1 << $j);
  
            // Predefined binary search in PHP
            $isl = in_array($lx, $x);
            $isr = in_array($rx, $x);
  
            // If possible to get sub-set of size 3
            if ($isl && $isr && count($res) < 3)
            {
                unset($res);
                $res = array();
                array_push($res, $lx);
                array_push($res, $x[$i]);
                array_push($res, $rx);
            }
  
            // If possible to get sub-set of size 2
            if ($isl && count($res) < 2)
            {
                unset($res);
                $res = array();
                array_push($res, $lx);
                array_push($res, $x[$i]);
            }
  
            // If possible to get sub-set of size 2
            if ($isr && count($res) < 2)
            {
                unset($res);
                $res = array();
                array_push($res, $x[$i]);
                array_push($res, $rx);
            }
        }
    }
  
    // If not possible to get sub-set
    if (!count($res))
    {
        echo "-1";
        return;
    }
  
    // Print the sub-set
    for ($i = 0; $i < count($res); $i++)
        echo $res[$i] . " ";
}
  
// Driver Code
$a = array( 3, 4, 5, 6, 7 );
  
$n = count($a);
PowerOfTwo($a, $n);
  
// This code is contributed by chandan_jnu
?>

chevron_right


Output:

3 5 7


My Personal Notes arrow_drop_up

pawanasipugmailcom

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : AnkitRai01, Chandan_Kumar