I am trying to find all numbers between 1 and 10000000 (both inclusive). I tried two solutions
- Brute Force Approach: Loop over all the numbers from 1 to 10000000, and find all which are divisible by either 3 or 5 or both.
- Divide & Conquer approach: Having 4 counters (2 from start and 2 from end). 2 counters work on multiples of 3 and two work on multiples of 5. I am putting all multiples in a Set (I do not need Sorted elements, I only need elements , sorting increases my complexity as well).
But, the loop approach is taking smaller time than the 'Divide & Conquer approach' (10 times lesser approximately). I searched for the solutions online as well. But, I could find loop approach only. Is there something I am missing in my approach which is increasing my execution time? Please point me to that. I started from a List, moved to Sorted Set, then finally settled to use HashSet, but seems to take time.
Here is what I tried.
`
public static void main(String[] args) {
System.out.println("Numbers divisible by 3 and 5:");
nosDivisibleBy3And5(); // divide & conquer approach (approach to consider)
nosDivisibleBy3And5BruteForce();
}
private static void nosDivisibleBy3And5BruteForce() {
IntStream ar = IntStream.range(1, 10000001); // start inclusive, end exclusive
Integer[] array = ar.boxed().toArray(Integer[]::new);
List<Integer> list = new ArrayList<>();
int count = 0;
long start = System.currentTimeMillis();
/*
* Traversing array from 1 to 100,
* if it is either divisible by 3 or 5 or both, count it , print it.
*
*/
for(int i = 0; i < array.length ; i ++) {
if((array[i] % 3 == 0) || (array[i] % 5 == 0)) {
//System.out.println(array[i]);
list.add(array[i]);
count++;
}
}
long end = System.currentTimeMillis();
System.out.println("Brute Force Approach:");
System.out.println("No of elements counted: " + count);
//Collections.sort(list);
//System.out.println("Elements: " + list);
System.out.println("Time: " + (end - start));
}
private static void nosDivisibleBy3And5() {
/*
* Set has all those numbers which
* are divisible by both 3 and 5.
*
*/
Set<Integer> elementsSet = new HashSet<Integer>();
int fr3,
fr5,
mid,
count;
fr3 = 2; // fr3 indicates the index of the first value divisible by 3.
fr5 = 4; // fr5 indicates the index of the first value divisible by 5.
count = 0;
int end3 = 9999998 , // end3 indicates the index of the last value divisible by 3.
end5 = 9999999; // end5 indicates the index of the last value divisible by 5.
/* Getting all the numbers from 1 to 100 from Intstream object */
IntStream ar = IntStream.range(1, 10000001); // start inclusive, end exclusive
Integer[] array = ar.boxed().toArray(Integer[]::new);
/*
* Using divide and conquer approach , mid divides the array from 1 to 100
* in two parts, on the first fr3 and fr5 will work, on the second part end3
* and end5 will work.
*/
mid = (fr3 + end3)/2;
long start = System.currentTimeMillis();
while(fr3 <= mid && end3 >= mid) {
elementsSet.add(array[fr3]);
elementsSet.add(array[fr5]);
elementsSet.add(array[end3]);
elementsSet.add(array[end5]);
fr3 += 3;
fr5 += 5;
end3 -= 3;
end5 -= 5;
}
long end = System.currentTimeMillis();
System.out.println("Our approach");
System.out.println("No of elements counted: " + elementsSet.size());
//System.out.println("Elements:" + elementsSet);
System.out.println("Time: " + (end - start));
}
}
`