Power of Three
Check whether n is a power of three by repeatedly dividing by 3 instead of comparing logarithms, which floating point error can corrupt.
Open on LeetCode ↗Intuition
Using logarithms feels like the fast path: if log(n) / log(3) is a whole number, n is a power of three. But floating point arithmetic is not exact, and log(243) / log(3) can evaluate to something like 4.999999999999999 instead of a clean 5.0, which fails a naive integer check even though 243 really is 3^5. The reliable fix stays entirely in integer land: repeatedly divide n by 3 as long as it divides evenly, and see what is left over. If you strip out every factor of 3 and land exactly on 1, n was a pure power of three; if you hit a point where 3 no longer divides evenly and the remainder is not 1, n had some other prime factor mixed in. No floating point ever enters the picture.
Unlike powers of two, there's no bit trick — 3 isn't the base the hardware counts in. Dividing out every factor of 3 and checking whether 1 remains is the honest O(log n) answer, and the positivity guard comes first as always.
Approach
Reject non-positive n immediately
Powers of three are always >= 1, so any n <= 0 can be answered false without doing any division.
Repeatedly divide by 3 while divisible
While n is evenly divisible by 3 (n % 3 == 0), divide it by 3 and continue. Each successful division strips exactly one factor of 3 out of n, using only integer arithmetic with no rounding error.
Check if the result is exactly 1
Once n is no longer divisible by 3, the loop stops. If what remains is exactly 1, every factor of n was a 3 and it is a genuine power of three; any other leftover value means n had a different prime factor.
Solution & live demo
Common pitfalls
Omitting the positivity guard
while n % 3 == 0:
n //= 3
return n == 1if n <= 0:
return FalseZero divides by 3 forever without changing, so the loop never terminates. Negative values fall straight through to a false n == 1 in some languages and loop in others.
Using a floating-point logarithm
return math.log(n, 3).is_integer()
while n % 3 == 0: n //= 3
log(243, 3) can evaluate to 4.999999999999999 due to rounding, reporting a genuine power of three as false. Integer division has no such failure mode.
Reaching for a bit trick
return (n & (n - 1)) == 0
while n % 3 == 0: n //= 3
That tests powers of two — the identity depends on binary representation and has no analogue for base 3. The only constant-time alternative is checking divisibility into the largest power of 3 that fits in an int.
Edge cases
n % 3 != 0 immediately (1 is not divisible by 3), so the loop never runs, and n == 1 is true -- correctly a power of three.
Handled by an explicit early return of false, since the division loop assumes a positive starting value.
Division strips the two factors of 3 to reach 5, then stops since 5 % 3 != 0, and 5 != 1, so the result is correctly false.
Repeated integer division handles this exactly since it never leaves integer arithmetic, unlike a logarithm-based comparison which loses precision at scale.