- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Max occurring divisor in an interval
Let x and y be two numbers. In this case, x is said to be a divisor of y if when y is divided by x it returns zero remainder. The maximum occurring divisor in an interval is the number that is a divisor of the maximum number of elements of that interval.
Problem Statement
Given an interval [a, b]. Find the maximum occurring divisor in the range including both a and b, except ‘1’. In case all divisors have equal occurrence, return 1.
Sample Example 1
Input [2, 5]
Output 2
Explanation − Divisors of 2 = {1, 2}, Divisors of 3 = {1, 3}, Divisors of 4 = {1, 2, 4}, Divisors of 5 = {1, 5}. 2 is the most occurring divisor.
Sample Example 2
Input [2, 5]
Output 2
Explanation − Divisors of 2 = {1, 2}, Divisors of 3 = {1, 3}, Divisors of 4 = {1, 2, 4}, Divisors of 5 = {1, 5}. 2 is the most occurring divisor.
Approach 1: Brute Force
The brute force approach to the problem will be to find all the divisors of all the numbers in the interval and store them in a map along with their number of occurrences.
Algorithm
procedure divisors (num)
for i = 1 to n1/2+1
if num%i == 0
if num/i == i
if i is not in the map then insert (i, 1)
else map[i]++
else
if i is not in the map then insert (i, 1)
else map[i]++
if num/i is not in the map then insert (num/i, 1)
else map[num/i]++
Procedure maxDivisors (a, b)
for n = a to b
divisors (n)
map.erase(1)
divisor = 1, count = int_min
for every element in the map it
if it.value > count
count = it.value
divisor = it.key
Example: C++ Implementation
In the following program, we find divisors of each number in the divisors() function and the maximum occurring divisor in the maxdivisor() function.
#include <bits/stdc++.h> using namespace std; // map storing occurrence of each divisor unordered_map<int, int> occ; // function to find all the divisors of a number and store it in map void divisors(int num){ for (int i = 1; i <= (sqrt(num) + 1); i++) { // checking if i is divisor of num if (num % i == 0) { // checking if num has identical divisors i.e. if i*i == num // if identical divisors then save only one if (num / i == i) { if (occ.find(i) == occ.end()) { occ.insert(make_pair(i, 1)); } else{ occ[i]++; } } else{ // saving divisor i if (occ.find(i) == occ.end()) { occ.insert(make_pair(i, 1)); } else{ occ[i]++; } // saving the divisor of num corresponding to i if (occ.find(num / i) == occ.end()) { occ.insert(make_pair(num / i, 1)); } else{ occ[num / i]++; } } } } } // function to find maximum occurring divisor in an interval int maxDivisor(int a, int b){ for (int n = a; n <= b; n++){ divisors(n); } // deleting all occurrences of 1 as 1 is not to be returned until the interval is [1,1] occ.erase(1); // divisor set as 1 for edge case scenario when interval is [1,1] int div = 1, cnt = INT_MIN; for (auto it = occ.begin(); it != occ.end(); it++) { if (it->second > cnt) { cnt = it->second; div = it->first; } } return div; } int main(){ int a = 4, b = 7; cout << "For the interval [" << a << ", " << b << "] maximum occurring divisor = "; cout << maxDivisor(a, b); return 0; }
Output
For the interval [4, 7] maximum occurring divisor = 2
Time Complexity − O(n3/2) because for every number in the interval, for finding the divisor a loop of complexity O(n1/2) is executed.
Space Complexity − O(n), map space.
Appraoch 2
The above approach can be optimised further by reducing the time to fill the map with the occurrence of each divisor. Rather than finding the divisor of each number, the occurrence of each divisor in the interval can be known by doing computations on the lower and upper bound of the interval.
Let’s take an example of the interval [2, 5].
The possible set of divisors is from 1 to 5. Thus occurrence of 1 = 5/1 - 2/1 +1 = 4. Occurrence of 2 = 5/2 - 2/2 + 1 = 2. Occurrence of 3 = 5/3 - 2/3 = 1. Occurrence of 4 = 5/4 - 2/4 = 1. Occurrence of 5 = 5/5 - 2/5 = 1.
The above can be formalised as,
if lower-bound%divisor == 0 then occ = upper-bound/divisor - lower-bound/divisor + 1
else occ = upper-bound/divisor - lower-bound/divisor
Algorithm
procedure maxDivisor (a, b)
for i = 2 to b
if a%i == 0
times = b/i - a/i +1
else
times = b/i - a/i
map.insert(i, times)
divisor = 1, count = int_min
for every element in the map it
if it.value > count
count = it.value
divisor = it.key
Example: C++ Implementation
In the following program, rather than finding the divisors of a number we go in the reverse order and for each divisor find how many multiples it has in the interval.
#include <bits/stdc++.h> using namespace std; // function to find maximum occurring divisor in an interval int maxDivisor(int a, int b){ // map used to store occurrences of divisors unordered_map<int, int> occ; for (int i = 2; i <= b; i++){ int times; if (a % i == 0){ times = (b / i) - (a / i) + 1; } else{ times = (b / i) - (a / i); } occ.insert(make_pair(i, times)); } // divisor set as 1 for edge case scenario when interval is [1,1] int div = 1, cnt = INT_MIN; for (auto it = occ.begin(); it != occ.end(); it++){ if (it->second > cnt){ cnt = it->second; div = it->first; } } return div; } int main(){ int a = 1, b = 10; cout << "For the interval [" << a << ", " << b << "] maximum occurring divisor = "; cout << maxDivisor(a, b); return 0; }
Output
For the interval [1, 10] maximum occurring divisor = 2
Approach 3
A very simple solution to the problem is observed as follows,
In any interval with size > 1, half of the numbers (every even number) will have 2 as their divisor.
Thus it can be used as follows.
Algorithm
procedure maxDivisors (a, b)
if a == b
ans = a
else
ans = 2
Example: C++ Implementation
In the following program, we implement the observation that every even number has 2 as a divisor.
#include <bits/stdc++.h> using namespace std; // function to find the maximum occurring divisor in an interval int maxDivisor(int a, int b){ if (a == b){ return a; } else { return 2; } } int main(){ int a = 1, b = 10; cout << "For the interval [" << a << ", " << b << "] maximum occurring divisor = "; cout << maxDivisor(a, b); return 0; }
Output
For the interval [1, 10] maximum occurring divisor = 2
Conclusion
In conclusion, in order to find maximum occurring divisor in an interval, we can use the above approaches that range in time from O(n3/2) to O(1) and in space from O(n) to O(1).