I am doing the following programming exercise: Strongest even number in an interval. The statement is:
A strongness of an even number is the number of times we can successively divide by 2 until we reach an odd number starting with an even number n.
For example, if n = 12, then
12 / 2 = 6
6 / 2 = 3
we divided successively 2 times and we reached 3, so the strongness of 12 is 2.
If n = 16 then
16 / 2 = 8
8 / 2 = 4
4 / 2 = 2
2 / 2 = 1
we divided successively 4 times and we reached 1, so the strongness of 16 is 4 Task
Given a closed interval [n, m], return the even number that is the strongest in the interval. If multiple solutions exist return the smallest strongest even number.
Note that programs must run within the alloted server time; a naive solution will probably time out. Constraints
1 <= n < m <= INT_MAX Examples
for the input [1, 2] return 2 (1 has strongness 0, 2 has strongness 1)
for the input [5, 10] return 8 (5, 7, 9 have strongness 0; 6, 10 have strongness 1; 8 has strongness 2)
for the input [48, 56] return 48
First I thought to store in a map each number as a key, and the number of times it is divisible by 2, as a value:
import java.util.*;
public class StrongestEvenNumber {
public static int strongestEven/**/(int n, int m) {
System.out.println("n: "+n);
System.out.println("m: "+m);
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int i = n, number = 0, strongness = 0; i <= m; i++){
for(number = i, strongness = 0; number % 2 == 0; strongness++){
number /= 2;
}
map.put(i, strongness);
}
Map.Entry<Integer, Integer> maxEntry = null;
for(Map.Entry<Integer,Integer> entry : map.entrySet()){
if(maxEntry == null || entry.getValue().compareTo(maxEntry.getValue()) > 0){
maxEntry = entry;
}
}
return maxEntry.getKey();
}
}
However, with large numbers, it runs out of heap memory space, or execution time runs out. For example with:
n: 1180381085
m: 2074186600
Java heap space runs out.
And with:
n: 324243
m: 897653214
Execution time runs out. The execution time exceeds 16000 ms
Then I tried to just store the number which is the most times divisible by 2:
import java.util.*;
public class StrongestEvenNumber {
public static int strongestEven/**/(int n, int m) {
System.out.println("n: "+n);
System.out.println("m: "+m);
int maxStrongness = 0, maxNumber = 0;
for(int i = n, number = 0, strongness = 0; i <= m; i++){
for(number = i, strongness = 0; number % 2 == 0; strongness++){
number /= 2;
}
if(strongness > maxStrongness){
maxStrongness = strongness;
maxNumber = i;
}
}
return maxNumber;
}
}
Indeed it solves the heap space difficulty, however the execution time runs out behaviour stills happening.
For example with:
n: 200275492
m: 1590463313
The execution time exceeds 16000 ms
I have also read:
- Finding Key associated with max Value in a Java Map
- Get the key for the maximum value in a HashMap using Collections
- https://math.stackexchange.com/questions/2589831/how-many-times-can-i-divide-a-number-by-another
- Number of times all the numbers in an array are divisible by 2
- optimize code to get the number of integers within given range that are divisible by integer