Maximum modulo of all the pairs of array where arr[i] >= arr[j]
Last Updated :
19 Sep, 2023
Given an array of n integers. Find the maximum value of arr[i] mod arr[j] where arr[i] >= arr[j] and 1 <= i, j <= n
Examples:
Input: arr[] = {3, 4, 7}
Output: 3
Explanation:
There are 3 pairs which satisfies arr[i] >= arr[j] are:-
4, 3 => 4 % 3 = 1
7, 3 => 7 % 3 = 1
7, 4 => 7 % 4 = 3
Hence Maximum value among all is 3.
Input: arr[] = {3, 7, 4, 11}
Output: 4
Input: arr[] = {4, 4, 4}
Output: 0
A Naive approach is to run two nested for loops and select the maximum of every possible pairs after taking modulo of them. Time complexity of this approach will be O(n2) which will not be sufficient for large value of n.
An efficient approach (when elements are from small range) is to use sorting and binary search method. Firstly we will sort the array so that we would able to apply binary search on it. Since we need to maximize the value of arr[i] mod arr[j] so we iterate through each x(such x divisible by arr[j]) in range from 2*arr[j] to M+arr[j], where M is Maximum value of sequence. For each value of x we need to find maximum value of arr[i] such that arr[i] < x.
By doing this we would assure that we have chosen only those values of arr[i] that will give the maximum value of arr[i] mod arr[j]. After that we just need to repeat the above process for other values of arr[j] and update the answer by value a[i] mod arr[j].
For example:-
If arr[] = {4, 6, 7, 8, 10, 12, 15} then for
first element, i.e., arr[j] = 4 we iterate
through x = {8, 12, 16}.
Therefore for each value of x, a[i] will be:-
x = 8, arr[i] = 7 (7 < 8)
ans = 7 mod 4 = 3
x = 12, arr[i] = 10 (10 < 12)
ans = 10 mod 4 = 2 (Since 2 < 3,
No update)
x = 16, arr[i] = 15 (15 < 16)
ans = 15 mod 4 = 3 (Since 3 == 3,
No need to update)
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int maxModValue( int arr[], int n)
{
int ans = 0;
sort(arr, arr + n);
for ( int j = n - 2; j >= 0; --j) {
if (ans >= arr[j])
break ;
if (arr[j] == arr[j + 1])
continue ;
for ( int i = 2 * arr[j]; i <= arr[n - 1] + arr[j]; i += arr[j]) {
int ind = lower_bound(arr, arr + n, i) - arr;
ans = max(ans, arr[ind - 1] % arr[j]);
}
}
return ans;
}
int main()
{
int arr[] = { 3, 4, 5, 9, 11 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << maxModValue(arr, n);
}
|
Java
import java.util.Arrays;
class Test {
static int maxModValue( int arr[], int n)
{
int ans = 0 ;
Arrays.sort(arr);
for ( int j = n - 2 ; j >= 0 ; --j) {
if (ans >= arr[j])
break ;
if (arr[j] == arr[j + 1 ])
continue ;
for ( int i = 2 * arr[j]; i <= arr[n - 1 ] + arr[j]; i += arr[j]) {
int ind = Arrays.binarySearch(arr, i);
if (ind < 0 )
ind = Math.abs(ind + 1 );
else {
while (arr[ind] == i) {
ind--;
if (ind == 0 ) {
ind = - 1 ;
break ;
}
}
ind++;
}
ans = Math.max(ans, arr[ind - 1 ] % arr[j]);
}
}
return ans;
}
public static void main(String args[])
{
int arr[] = { 3 , 4 , 5 , 9 , 11 };
System.out.println(maxModValue(arr, arr.length));
}
}
|
Python3
def maxModValue(arr, n):
ans = 0
arr = sorted (arr)
for j in range (n - 2 , - 1 , - 1 ):
if (ans > = arr[j]):
break
if (arr[j] = = arr[j + 1 ]) :
continue
i = 2 * arr[j]
while (i < = arr[n - 1 ] + arr[j]):
ind = 0
for k in arr:
if k > = i:
ind = arr.index(k)
ans = max (ans, arr[ind - 1 ] % arr[j])
i + = arr[j]
return ans
arr = [ 3 , 4 , 5 , 9 , 11 ]
n = 5
print (maxModValue(arr, n))
|
C#
using System;
public class GFG {
static int maxModValue( int [] arr, int n)
{
int ans = 0;
Array.Sort(arr);
for ( int j = n - 2; j >= 0; --j)
{
if (ans >= arr[j])
break ;
if (arr[j] == arr[j + 1])
continue ;
for ( int i = 2 * arr[j];
i <= arr[n - 1] + arr[j];
i += arr[j])
{
int ind = Array.BinarySearch(arr, i);
if (ind < 0)
ind = Math.Abs(ind + 1);
else {
while (arr[ind] == i) {
ind--;
if (ind == 0) {
ind = -1;
break ;
}
}
ind++;
}
ans = Math.Max(ans, arr[ind - 1]
% arr[j]);
}
}
return ans;
}
public static void Main()
{
int [] arr = { 3, 4, 5, 9, 11 };
Console.WriteLine(
maxModValue(arr, arr.Length));
}
}
|
Javascript
<script>
function maxModValue(arr, n) {
let ans = 0;
arr.sort((a, b) => a - b);
for (let j = n - 2; j >= 0; --j) {
if (ans >= arr[j])
break ;
if (arr[j] == arr[j + 1])
continue ;
for (let i = 2 * arr[j]; i <= arr[n - 1] + arr[j];
i += arr[j])
{
let ind = arr.indexOf(i);
if (ind < 0)
ind = Math.abs(ind) + 1;
else {
while (arr[ind] == i) {
ind--;
if (ind == 0) {
ind = -1;
break ;
}
}
ind++;
}
ans = Math.max(ans, arr[ind - 1] % arr[j]);
}
}
return ans;
}
let arr = [3, 4, 5, 9, 11];
document.write(maxModValue(arr, arr.length));
</script>
|
ime complexity: O(nlog(n) + Mlog(M)) where n is total number of elements and M is maximum value of all the elements.
Auxiliary space: O(1)
This blog is contributed by Shubham Bansal.
Share your thoughts in the comments
Please Login to comment...