The question is:
Write a boolean method, that get positive integer n>0. and return, if this n can be write as a power of 3's. each power, can appear at the sum maximum one time.
For example: if n = 37 f() return true, because: 3^0 3^2 3^3 = 37 if n = 38 f() return false.
I was able to solve the problem, but only when i wrote the condition (num==0) before the condition (num < 0 || 3^I > num).
can anyone explain me why?
the 2 versions of the code:
public static boolean sumPower3(int num)
{ return sumPower3(num,0); }
// version 1(output: false):
private static boolean sumPower3(int n,int i)
{
int p3i = (int)Math.pow(3,i);
if(p3i>n || n<0){return false;}
if(n==0){return true;}
return sumPower3(n-p3i,i 1) || sumPower3(n,i 1);
}
// version 2 (output true):
private static boolean sumPower3(int n,int i)
{
int p3i = (int)Math.pow(3,i);
if(n==0){return true;}
if(p3i>n || n<0){return false;}
return sumPower3(n-p3i,i 1) || sumPower3(n,i 1);
}
CodePudding user response:
For version 1, consider what happens in the last layer of recurision.
At this point, n
is already equal to 0. The answer to this should be true
, and that is what should be returned.
However, (int)Math.pow(3,i);
is definitely larger than or equal to 1. This means that when n == 0
, p3i>n
will evaluate to true
and your function returns false
, giving an incorrect answer.
You should write the n == 0
condition first as p3i>n || n<0
should only return false when n != 0
.
CodePudding user response:
Alternative "math" solution:
public static boolean sumPower3(int num) {
if (num == 1 || num == 0) {
return true;
}
if (num % 3 == 2) {
return false;
}
return sumPower3(num / 3);
}