Open In App

Check if all array elements can be reduced to less than X

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array A[] consisting of N positive integers and an integer X, the task is to determine if it is possible to convert all array elements to less than X by performing the following operations:

  • Select 2 distinct indices j and k.
  • Select an index i, where A[i] > X.
  • Replace A[i] = gcd(A[j], A[k]) if and only if gcd(A[j], A[k]) ? 1.

Examples: 

Input: A[] = {2, 1, 5, 3, 6}, X = 4 
Output: Yes 
Explanation:

  • Selecting i = 3, j = 4, k = 5, set A[i] = gcd(A[j], A[k]) = 3. Therefore, A[] modifies to {2, 1, 3, 3, 6}.
  • Selecting i = 5, j = 4, k = 5, set A[i] = gcd(A[j], A[k]) = 3. Therefore, A[] modifies to {2, 1, 3, 3, 3}.

Input: A[] = {2, 3, 2, 5, 4}, X = 3 
Output: Yes

Approach: Follow the steps below to solve the problem: 

  1. Find the two numbers having gcd ? 1 as well as gcd ? X, then, by using these two numbers, the required number A[i] can be replaced with gcd(A[j], A[k]).
  2. Using the fact that gcd(x, y) ? min(x, y), the array elements can be reduced to ? X.
  3. This way, the rest of the array can be converted to ? X using step 2.

Below is the implementation of the above approach:

C++




// C++ program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if all array
// elements are? X
bool check(int A[], int X, int N)
{
    for(int i = 0; i < N; i++)
    {
        if (A[i] > X)
        {
            return false;
        }
    }
    return true;
}
 
// Function to check if all array elements
// can be reduced to less than X or not
bool findAns(int A[], int N, int X)
{
     
    // Checks if all array elements
    // are already ? X or not
    if (check(A, X, N))
    {
        return true;
    }
 
    // Traverse every possible pair
    for(int i = 0; i < N; i++)
    {
        for(int j = i + 1; j < N; j++)
        {
             
            // Calculate GCD of two
            // array elements
            int g = __gcd(A[i], A[j]);
 
            // If gcd is ? 1
            if (g != 1)
            {
                 
                // If gcd is ? X, then a pair
                // is present to reduce all
                // array elements to ? X
                if (g <= X)
                {
                    return true;
                }
            }
        }
    }
     
    // If no pair is present
    // with gcd is ? X
    return false;
}
 
// Driver Code
int main()
{
    int X = 4;
    int A[] = { 2, 1, 5, 3, 6 };
    int N = 5;
     
    if (findAns(A, N, X))
    {
        cout << "true";
    }
    else
    {
        cout << "false";
    }
}
 
// This code is contributed by mohit kumar 29


Java




// Java Program to implement
// the above approach
 
import java.io.*;
import java.util.Arrays;
 
class GFG {
 
    // Function to check if all array elements
    // can be reduced to less than X or not
    public static boolean findAns(
        int[] A, int N, int X)
    {
        // Checks if all array elements
        // are already ? X or not
        if (check(A, X)) {
            return true;
        }
 
        // Traverse every possible pair
        for (int i = 0; i < N; i++) {
            for (int j = i + 1; j < N; j++) {
 
                // Calculate GCD of two
                // array elements
                int gcd = gcd(A[i], A[j]);
 
                // If gcd is ? 1
                if (gcd != 1) {
 
                    // If gcd is ? X, then a pair
                    // is present to reduce all
                    // array elements to ? X
                    if (gcd <= X) {
 
                        return true;
                    }
                }
            }
        }
 
        // If no pair is present
        // with gcd is ? X
        return false;
    }
 
    // Function to check if all array elements are? X
    public static boolean check(int[] A, int X)
    {
        for (int i = 0; i < A.length; i++) {
            if (A[i] > X) {
                return false;
            }
        }
        return true;
    }
 
    // Function to calculate gcd of two numbers
    public static int gcd(int a, int b)
    {
        if (b == 0)
            return a;
        return gcd(b, a % b);
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int X = 4;
        int[] A = { 2, 1, 5, 3, 6 };
        int N = 5;
 
        System.out.println(findAns(A, N, X));
    }
}


Python3




# Python3 program to implement
# the above approach
 
# Function to check if all array elements
# can be reduced to less than X or not
def findAns(A, N, X):
   
  # Checks if all array elements
  # are already ? X or not
  if (check(A, X)):
    return True
         
  # Traverse every possible pair
  for i in range(N):
    for j in range(i + 1, N):
       
      # Calculate GCD of two
      # array elements
      gcd = GCD(A[i], A[j])
 
      # If gcd is ? 1
      if (gcd != 1):
         
        # If gcd is ? X, then a pair
        # is present to reduce all
        # array elements to ? X
        if (gcd <= X):
          return True
 
  # If no pair is present
  # with gcd is ? X
  return False
 
# Function to check if all array elements are? X
def check(A, X):
  for i in range(len(A)):
    if (A[i] > X):
      return False
  return True
 
# Function to calculate gcd of two numbers
def GCD(a, b):
  if (b == 0):
    return a
  return GCD(b, a % b)
 
# Driver Code
X = 4
A = [ 2, 1, 5, 3, 6 ]
N = 5
 
print(findAns(A, N, X))
 
# This code is contributed by rohitsingh07052


C#




// C# Program to implement
// the above approach
using System;
class GFG {
 
    // Function to check if all array elements
    // can be reduced to less than X or not
    public static bool findAns(
        int[] A, int N, int X)
    {
        // Checks if all array elements
        // are already ? X or not
        if (check(A, X))
        {
            return true;
        }
 
        // Traverse every possible pair
        for (int i = 0; i < N; i++)
        {
            for (int j = i + 1; j < N; j++)
            {
 
                // Calculate GCD of two
                // array elements
                int gcd = gcdFoo(A[i], A[j]);
 
                // If gcd is ? 1
                if (gcd != 1)
                {
 
                    // If gcd is ? X, then a pair
                    // is present to reduce all
                    // array elements to ? X
                    if (gcd <= X)
                    {
                        return true;
                    }
                }
            }
        }
 
        // If no pair is present
        // with gcd is ? X
        return false;
    }
 
    // Function to check if all array elements are? X
    public static bool check(int[] A, int X)
    {
        for (int i = 0; i < A.Length; i++)
        {
            if (A[i] > X)
            {
                return false;
            }
        }
        return true;
    }
 
    // Function to calculate gcd of two numbers
    static int gcdFoo(int a, int b)
    {
        if (b == 0)
            return a;
        return gcdFoo(b, a % b);
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        int X = 4;
        int[] A = { 2, 1, 5, 3, 6 };
        int N = 5;
 
        Console.WriteLine(findAns(A, N, X));
    }
}
 
// This code is contributed by 29AjayKumar


Javascript




<script>
// javascript program of the above approach
 
    // Function to check if all array elements
    // can be reduced to less than X or not
    function findAns(
         A, N, X)
    {
        // Checks if all array elements
        // are already ? X or not
        if (check(A, X)) {
            return true;
        }
  
        // Traverse every possible pair
        for (let i = 0; i < N; i++) {
            for (let j = i + 1; j < N; j++) {
  
                // Calculate GCD of two
                // array elements
                let gcdd = gcd(A[i], A[j]);
  
                // If gcd is ? 1
                if (gcdd != 1) {
  
                    // If gcd is ? X, then a pair
                    // is present to reduce all
                    // array elements to ? X
                    if (gcdd <= X) {
  
                        return true;
                    }
                }
            }
        }
  
        // If no pair is present
        // with gcd is ? X
        return false;
    }
  
    // Function to check if all array elements are? X
    function check(A, X)
    {
        for (let i = 0; i < A.length; i++) {
            if (A[i] > X) {
                return false;
            }
        }
        return true;
    }
  
    // Function to calculate gcd of two numbers
    function gcd(a, b)
    {
        if (b == 0)
            return a;
        return gcd(b, a % b);
    }
  
 
    // Driver Code
     
        let X = 4;
        let A = [ 2, 1, 5, 3, 6 ];
        let N = 5;
  
        document.write(findAns(A, N, X));
 
// This code is contributed by target_2.
</script>


Output

true



 Time Complexity: O(N2
Auxiliary Space: O(1)

New Approach:- Here, Another approach to solve this problem is by using Binary Search. We can perform a binary search on the range of possible values for the final array. We can set the lower bound to be 1 and the upper bound to be the maximum value in the array. For each mid value, we can check if it is possible to reduce all the array elements to less than or equal to this value.

To check this, we can iterate over all pairs of elements in the array and check if their gcd is either 1 or less than or equal to the mid value. If we find such a pair, we can update the value of mid to be the gcd of this pair.

If we find a mid value for which it is possible to reduce all array elements to less than or equal to this value, we can move the upper bound to mid. Otherwise, we can move the lower bound to mid + 1.

Below is the implementation of this approach:

C++




#include <bits/stdc++.h>
using namespace std;
 
// Function to check if all array elements
// can be reduced to less than or equal to X
bool canReduce(int A[], int N, int X) {
    for (int i = 0; i < N; i++) {
        if (A[i] > X) {
            bool foundPair = false;
            for (int j = 0; j < N; j++) {
                for (int k = j + 1; k < N; k++) {
                    int gcd = __gcd(A[j], A[k]);
                    if (gcd != 1 && gcd <= X) {
                        foundPair = true;
                        X = gcd;
                        break;
                    }
                }
                if (foundPair) {
                    break;
                }
            }
            if (!foundPair) {
                return false;
            }
        }
    }
    return true;
}
 
// Function to check if all array elements
// can be reduced to less than or equal to X
// using binary search
bool findAns(int A[], int N, int X) {
    int low = 1;
    int high = *max_element(A, A + N);
    while (low < high) {
        int mid = low + (high - low) / 2;
        if (canReduce(A, N, mid)) {
            high = mid;
        } else {
            low = mid + 1;
        }
    }
    return canReduce(A, N, low);
}
 
// Driver Code
int main() {
    int X = 4;
    int A[] = { 2, 1, 5, 3, 6 };
    int N = 5;
    if (findAns(A, N, X)) {
        cout << "true";
    } else {
        cout << "false";
    }
    return 0;
}


Java




import java.util.*;
 
public class Main {
     
    public static void main(String[] args) {
        int X = 4;
        int[] A = {2, 1, 5, 3, 6};
        int N = 5;
        if (findAns(A, N, X)) {
            System.out.println("true");
        } else {
            System.out.println("false");
        }
    }
     
    // Function to check if all array elements
    // can be reduced to less than or equal to X
    public static boolean canReduce(int[] A, int N, int X) {
        for (int i = 0; i < N; i++) {
            if (A[i] > X) {
                boolean foundPair = false;
                for (int j = 0; j < N; j++) {
                    for (int k = j + 1; k < N; k++) {
                        int gcd = gcd(A[j], A[k]);
                        if (gcd != 1 && gcd <= X) {
                            foundPair = true;
                            X = gcd;
                            break;
                        }
                    }
                    if (foundPair) {
                        break;
                    }
                }
                if (!foundPair) {
                    return false;
                }
            }
        }
        return true;
    }
     
    // Function to check if all array elements
    // can be reduced to less than or equal to X
    // using binary search
    public static boolean findAns(int[] A, int N, int X) {
        int low = 1;
        int high = Arrays.stream(A).max().getAsInt();
        while (low < high) {
            int mid = low + (high - low) / 2;
            if (canReduce(A, N, mid)) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }
        return canReduce(A, N, low);
    }
     
    // Function to calculate the gcd of two numbers
    public static int gcd(int a, int b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
    }
}


Python3




import math
 
# Function to check if all array elements
# can be reduced to less than or equal to X
def canReduce(A, N, X):
    for i in range(N):
        if A[i] > X:
            foundPair = False
            for j in range(N):
                for k in range(j + 1, N):
                    gcd = math.gcd(A[j], A[k])
                    if gcd != 1 and gcd <= X:
                        foundPair = True
                        X = gcd
                        break
                if foundPair:
                    break
            if not foundPair:
                return False
    return True
 
# Function to check if all array elements
# can be reduced to less than or equal to X
# using binary search
def findAns(A, N, X):
    low = 1
    high = max(A)
    while low < high:
        mid = low + (high - low) // 2
        if canReduce(A, N, mid):
            high = mid
        else:
            low = mid + 1
    return canReduce(A, N, low)
 
# Driver Code
if __name__ == '__main__':
    X = 4
    A = [2, 1, 5, 3, 6]
    N = 5
    if findAns(A, N, X):
        print("true")
    else:
        print("false")


C#




using System;
using System.Linq;
 
public class ArrayReduction
{
    // Function to check if all array elements can be reduced to less than or equal to X
    static bool CanReduce(int[] A, int N, int X)
    {
        for (int i = 0; i < N; i++)
        {
            if (A[i] > X)
            {
                bool foundPair = false;
                for (int j = 0; j < N; j++)
                {
                    for (int k = j + 1; k < N; k++)
                    {
                        int gcd = GCD(A[j], A[k]);
                        if (gcd != 1 && gcd <= X)
                        {
                            foundPair = true;
                            X = gcd;
                            break;
                        }
                    }
                    if (foundPair)
                    {
                        break;
                    }
                }
                if (!foundPair)
                {
                    return false;
                }
            }
        }
        return true;
    }
 
    // Function to find the greatest common divisor (GCD) of two numbers
    static int GCD(int a, int b)
    {
        while (b != 0)
        {
            int temp = b;
            b = a % b;
            a = temp;
        }
        return a;
    }
 
    // Function to check if all array elements can be reduced to less than or equal to X using binary search
    static bool FindAns(int[] A, int N, int X)
    {
        int low = 1;
        int high = A.Max();
 
        while (low < high)
        {
            int mid = low + (high - low) / 2;
            if (CanReduce(A, N, mid))
            {
                high = mid;
            }
            else
            {
                low = mid + 1;
            }
        }
        return CanReduce(A, N, low);
    }
 
    // Driver Code
    public static void Main(string[] args)
    {
        int X = 4;
        int[] A = { 2, 1, 5, 3, 6 };
        int N = 5;
 
        if (FindAns(A, N, X))
        {
            Console.WriteLine("true");
        }
        else
        {
            Console.WriteLine("false");
        }
    }
}


Javascript




// Function to check if all array elements
// can be reduced to less than or equal to X
function canReduce(arr, X) {
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] > X) {
            let foundPair = false;
            for (let j = 0; j < arr.length; j++) {
                for (let k = j + 1; k < arr.length; k++) {
                    let gcd = calculateGCD(arr[j], arr[k]);
                    if (gcd !== 1 && gcd <= X) {
                        foundPair = true;
                        X = gcd;
                        break;
                    }
                }
                if (foundPair) {
                    break;
                }
            }
            if (!foundPair) {
                return false;
            }
        }
    }
    return true;
}
 
// Function to calculate the greatest common divisor (GCD)
function calculateGCD(a, b) {
    if (b === 0) {
        return a;
    }
    return calculateGCD(b, a % b);
}
 
// Function to check if all array elements
// can be reduced to less than or equal to X
// using binary search
function findAns(arr, X) {
    let low = 1;
    let high = Math.max(...arr);
    while (low < high) {
        let mid = low + Math.floor((high - low) / 2);
        if (canReduce(arr, mid)) {
            high = mid;
        } else {
            low = mid + 1;
        }
    }
    return canReduce(arr, low);
}
 
// Driver Code
const X = 4;
const A = [2, 1, 5, 3, 6];
const N = 5;
 
if (findAns(A, N, X)) {
    console.log("true");
} else {
    console.log("false");
}


Output

true



“Note that the time complexity of this approach is O(N^3 log(max(A))), where N is the length of the array and max(A) is the maximum value in the array. This is because for each mid value, we need to iterate over all pairs of elements in the array, and for each pair, we need to calculate their gcd, which has a worst-case time complexity of O(log(max(A))). The overall space complexity is O(1).”

Time Complexity:- The time complexity of the canReduce function is O(N^3) because it has three nested loops. The outer loop runs N times, and the inner two loops run N(N-1)/2 times, so the total number of iterations is N^3/2.

The time complexity of the findAns function is O(N^4 log MAX), where MAX is the maximum element in the array. This is because the canReduce function is called for each value of mid in the binary search, and the canReduce function has a time complexity of O(N^3). Therefore, the total time complexity is O(N^3 log MAX) for the binary search, plus an additional O(N^3) for the final call to canReduce with the lowest value of X that works.

Auxiliary Space:- The auxiliary space complexity of both functions is O(1), as they do not use any additional data structures that depend on the input size.



Last Updated : 28 Oct, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads