Basically what I wanted to is if a number n
is divisible by b
for a
(count) times, then find the a
(count), and divide n
by b
for a
(count) times.
That is,
count = 0;
while(n%b == 0)
n=n/b;
count = count + 1;
How to optimize this, so that everything can be obtained in one step
You can do it in O(log(a))
by applying binary search, on a sorted "list" to find the last element that equals 1.
The list is metaphoric, and each element in it is calculated on the fly when queried by a simple calculation:
list[i] = 1 n % a^i == 0
0 otherwise
You can first find the range of possible a
's using exponention:
curr = b
tempA = 1
while n % curr == 0:
curr = curr * curr
tempA = tempA *2
And then, run the binary search on the range [tempA/2, tempA]
. This range is of size (a/2)
, so finding the last "element" that the symbolic list holds 1
- is done in O(loga)
multiplications.
Code + Demo:
private static int specialBinarySearch(int n, int b, int aLow, int aHigh) {
if (aHigh == aLow) return aHigh;
int mid = (aHigh - aLow)/2 + aLow;
//pow method can be optimized to remember pre-calculated values and use them
int curr = (int)Math.round(Math.pow(b, mid));
if (n % curr == 0) { //2nd half, or found it:
if (n % (curr*b) != 0) return mid; //found it
return specialBinarySearch(n, b, mid+1, aHigh); //2nd half
}
else return specialBinarySearch(n, b, aLow, mid); //first half
}
public static int findA(int n, int b) {
int curr = b;
int tempA = 1;
while (n % curr == 0) {
curr = curr * curr;
tempA = tempA *2;
}
return specialBinarySearch(n, b, tempA/2, tempA);
}
public static void main(String args[]) {
System.out.println(findA(62,2)); //1
System.out.println(findA(1024,2)); //10
System.out.println(findA(1,2)); //0
System.out.println(findA(100,2)); //2
System.out.println(findA(6804,3)); //5
}
You cannot solve this in O(1) but there is a different kind of approach to this problem if you start using a numeric system where b
is the base.
For example, if we have a number like 154200, and b
is 10, we know the answer is 2 here immediately because we can simply count how many zeros there are on the right hand side.
Similarly, in binary, if b
is 2, you simply count how many zeros there are on the right side with a binary representation.
If b
is 5, we have to use the odd base 5 representation where a number like 8 is represented as 13. Again we know that the answer for a
is zero is n=8
and b=5
because there are no zeros on the right hand side.
This won't necessarily give you speed gains except possibly in cases where b
is a power of two where you can use bitwise logic to deduce the answer, but it gives you a different kind of way of looking at the problem lexically by digits instead of through arithmetic.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.