Given an array of length N that contains only integers, the task is to print the special numbers of array. A number in this array is called Special number if it is divisible by at least one other number in the array.
Examples :
Input : 1 2 3
Output : 2 3
Explanation : both 2 and 3 are divisible by 1.
Input : 2 3 4 6 8 9
Output : 4 6 8 9
Explanation : 2 and 3 are not divisible by any other element. Rest of the element are divisible by at-least 1 element. 6 is divisible by both 2 and 3, 4 divisible by 2, 8 divisible by 2 and 4 both, 9 divisible by 3.
Input : 3 5 7 11
Output :
Explanation : all elements are relatively prime so no special number.
A simple solution is to traverse through all elements, then check for every element if it is divisible by any other. Time complexity of this solution is O(n2)
Another solution that works better when there are many elements with not very big values. Store all array elements into hash and find out the max element in array then up-to max element find out the multiples of a given number then if multiple of array element is in hash then that number is divisible by at-least one element of array . To remove duplicate values we store the value into set because if array has 2, 3, and 6 then only 6 is divisible by at-least one element of array, both 2 and 3 divides 6 so 6 will be stored only one time.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
void divisibilityCheck( int arr[], int n)
{
unordered_set< int > s;
int max_ele = INT_MIN;
for ( int i = 0; i < n; i++) {
s.insert(arr[i]);
max_ele = max(max_ele, arr[i]);
}
unordered_set< int > res;
for ( int i = 0; i < n; i++) {
if (arr[i] != 0) {
for ( int j = arr[i] * 2; j <= max_ele; j += arr[i]) {
if (s.find(j) != s.end())
res.insert(j);
}
}
}
unordered_map< int , int > mp;
for ( int i = 0; i < n; i++)
mp[arr[i]]++;
unordered_map< int , int >::iterator it;
vector< int > ans;
for (it = mp.begin(); it != mp.end(); it++) {
if (it->second >= 2) {
if (res.find(it->first) == res.end()) {
int val = it->second;
while (val--)
ans.push_back(it->first);
}
}
if (res.find(it->first) != res.end()) {
int val = it->second;
while (val--)
ans.push_back(it->first);
}
}
for ( auto x : ans)
cout << x << " " ;
}
int main()
{
int arr[] = { 2, 3, 8, 6, 9, 10 };
int n = sizeof (arr) / sizeof (arr[0]);
divisibilityCheck(arr, n);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static void divisibilityCheck(List<Integer> arr,
int n)
{
List<Integer> s = new ArrayList<Integer>();
int max_ele = Integer.MIN_VALUE;
for ( int i = 0 ; i < n; i++) {
s.add(arr.get(i));
max_ele = Math.max(max_ele,
arr.get(i));
}
LinkedHashSet<Integer> res = new LinkedHashSet<Integer>();
for ( int i = 0 ; i < n; i++) {
if (arr.get(i) != 0 )
for ( int j = arr.get(i) * 2 ;
j <= max_ele;
j += arr.get(i)) {
if (s.contains(j))
res.add(j);
}
}
List<Integer> list = new ArrayList<Integer>(res);
Collections.reverse(list);
for (Integer temp : list)
System.out.print(temp + " " );
}
public static void main(String args[])
{
List<Integer> arr = Arrays.asList( 2 , 3 , 8 , 6 , 9 , 10 );
int n = arr.size();
divisibilityCheck(arr, n);
}
}
|
Python3
import math as mt
def divisibilityCheck(arr, n):
s = dict ()
max_ele = - 10 * * 9
for i in range (n):
s[arr[i]] = 1
max_ele = max (max_ele, arr[i])
res = dict ()
for i in range (n):
if (arr[i] ! = 0 ):
for j in range (arr[i] * 2 ,
max_ele + 1 , arr[i]):
if (j in s.keys()):
res[j] = 1
for x in res:
print (x, end = " " )
arr = [ 2 , 3 , 8 , 6 , 9 , 10 ]
n = len (arr)
divisibilityCheck(arr, n)
|
C#
using System;
using System.Linq;
using System.Collections.Generic;
class GFG {
static void divisibilityCheck(List< int > arr,
int n)
{
List< int > s = new List< int >();
int max_ele = Int32.MinValue;
for ( int i = 0; i < n; i++) {
s.Add(arr[i]);
max_ele = Math.Max(max_ele,
arr[i]);
}
HashSet< int > res = new HashSet< int >();
for ( int i = 0; i < n; i++) {
if (arr[i] != 0)
for ( int j = arr[i] * 2; j <= max_ele;
j += arr[i]) {
if (s.Contains(j))
res.Add(j);
}
}
foreach ( int i in res.Reverse())
Console.Write(i + " " );
}
static void Main()
{
List< int > arr = new List< int >() { 2, 3, 8,
6, 9, 10 };
int n = arr.Count;
divisibilityCheck(arr, n);
}
}
|
Javascript
<script>
function divisibilityCheck(arr, n) {
let s = new Set();
let max_ele = Number.MIN_SAFE_INTEGER;
for (let i = 0; i < n; i++) {
s.add(arr[i]);
max_ele = Math.max(max_ele, arr[i]);
}
let res = new Set();
for (let i = 0; i < n; i++) {
if (arr[i] != 0) {
for (let j = arr[i] * 2; j <= max_ele; j += arr[i]) {
if (s.has(j))
res.add(j);
}
}
}
let mp = new Map();
for (let i = 0; i < n; i++) {
if (mp.has(arr[i])) {
mp.set(arr[i], mp.get(arr[i]) + 1)
} else {
mp.set(arr[i], 1)
}
}
let ans = [];
for (let it of mp) {
if (it[1] >= 2) {
if (res.has(it[0])) {
let val = it[1];
while (val--)
ans.push(it[0]);
}
}
if (res.has(it[0])) {
let val = it[1];
while (val--)
ans.push(it[0]);
}
}
for (let x of ans.sort((a, b) => a - b))
document.write(x + " " );
}
let arr = [2, 3, 8, 6, 9, 10];
let n = arr.length
divisibilityCheck(arr, n);
</script>
|
Complexity Analysis:
- Time Complexity: O(n x m), where n is the size of array and m is the maximum element in array
- Auxiliary Space: O(n)
Please suggest if someone has a better solution which is more efficient in terms of space and time.
This article is contributed by Aarti_Rathi.
Note: If we need results to be printed in sorted order, we can use set in place of unordered_set.