【数学】C032_3的幂(除3判断 | 对数法 | 最大3的幂数)

一、题目描述

Given an integer, write a function to determine if it is a power of three.

Example 1:
Input: 27
Output: true

Follow up: Could you do it without using any loop / recursion?

二、题解

(1) 除3判断法

/**
 * @thought:找出数字 n 是否是 b 的幂数的通用做法是:n%b取余只要是0,那么一直将n/=b,
 * 如果n是b的幂,那么它可以被除以x次,知道最后n==1,是1%b==1,退出循环。(即b^0==1)
 * 但这不适用于负数。
 * @date: 1/17/2020 2:37 PM
 * @Execution info:
 *  ·执行用时 17 ms 击败了 27% 的java用户
 *  ·内存消耗 35.8MB 击败了 79% 的java用户
 * @Asymptotic Time Complexity:O(log_3(n)),在我们的例子中是 O(logn)。除数是用对数表示的。
 */
public boolean isPowerOfThree1(int n) {
  if(n < 1) return false;
  while(n%3 == 0)
    n/=3;
  return n==1;
}

复杂度分析

  • 时间复杂度: log 3 ( n ) \log_3(n) ,每次除以3,直到 n = = 1 n==1
  • 空间复杂度: O ( 1 ) O(1) ,只使用常数级别的内存。

(2) 对数法

n = 3 i n=3^i i = l o g 3 ( n ) i = log_3(n) ,换底得 i = l g ( n ) ÷ l g ( 3 ) i=lg_(n) \div lg_(3) ,如果i是整数,那么n为3的幂。

  • @problem:精度丢失问题,比较双精度数时不应该使用==,因为比较的结果可能是 5.0000001 或 4.9999999
  • 用 Math.log() 函数而不是Math.log10() 可以观察到这种效果。
/**
 * @thought:数学推导
 * @date: 1/17/2020 2:46 PM
 * @Execution info:
 *  ·执行用时 16 ms 击败了 45.22% 的java用户
 *  ·内存消耗 36MB 击败了 45% 的java用户
 * @Asymptotic Time Complexity:O()
 */
public boolean isPowerOfThree2(int n) {
  return (Math.log10(n)/Math.log10(3)) % 1 == 0;
  // return (Math.log(n)/Math.log(3) + epsilon) % 1 <= 2*epsilon;
}

(3) 利用最大3的幂数

/**
 * 利用最大的3次幂数1162261467对n取余是否等于0
 *
 * 这个最大3次幂数怎么推导出来呢?
 *
 * MaxInt = 2^32/2-1 == 2147483647因为我们使用 32 位来表示数字,
 * 所以范围的一半用于负数,0 是正数的一部分。知道了n的上限,也就知道n的最大值
 *
 * 14ms,O(1)
 * @param n
 * @return
 */
public boolean isPowerOfThree3(int n) {
  return (n > 0 && 1162261467%3==0);
}
发布了300 篇原创文章 · 获赞 48 · 访问量 8058

猜你喜欢

转载自blog.csdn.net/qq_43539599/article/details/104024787