数学-3的幂

给定一个整数,写一个函数来判断它是否是 3 的幂次方。

示例 1:

输入: 27
输出: true
示例 2:

输入: 0
输出: false
示例 3:

输入: 9
输出: true
示例 4:

输入: 45
输出: false

方法一:

用最常规的方法,直接用除余来判断

  • 如果余数为零就直接除3,一直循环到n为3为止
  • n == 1是因为一开始传过来的n就是1,3的0次方等于1,所以1也是对的
复杂度
  • 时间复杂度:O(log3n),除数是用对数表示的。
  • 空间复杂度:O(1),没有使用额外的空间。
func isPowerOfThree(n int) bool {
 if n == 0 {return false}
    for {
        if n==1 || n==3 {
            return true
        }
        if n % 3 == 0 {
            n = n / 3
        } else {
            return false
        }
        
    }


        // return n > 0 && 1162261467 % n == 0;

        if n < 1 {
        return false
    }
    s := strconv.FormatInt(int64(n), 3)
    return s[0:1] == "1" && strings.Count(s, "0") == len(s)-1

   
}

进阶:
你能不使用循环或者递归来完成本题吗?

方法二:

利用3进制来判断

  • 将n转化为3进制数的字符串,只要只有第一个数字为1,其他都为0,说明这个数是3的幂次方
复杂度
  • 时间复杂度:O(log3n)。
    假设:
    strconv.FormatInt() - 转换为3进制数,和方法一类似,都是求余。复杂性应该类似于方法一:O(log3n)的复杂性。
    regexp.MatchString - 方法迭代整个字符串。n 以 3 为基数表示的位数是O(log3n)。
  • 空间复杂度:O(log3n)。我们使用两个附加变量。
    以 3 为基数表示数字的字符串(大小为log3n) 正则表达式的字符串(常量大小)
func isPowerOfThree(n int) bool {
    if n < 1 {
        return false
    }
    s := strconv.FormatInt(int64(n), 3)
    //正则表达式,检查字符串是否以1 ^1 开头,后跟 0 或 多个 0* 并且不包含任何其他值 $。
    a,_ := regexp.MatchString("^10*$",s)
    return a
}

执行用时:108 ms, 在所有 Go 提交中击败了8.55%的用户
内存消耗:6.9 MB, 在所有 Go 提交中击败了11.48%的用户

能看到其实上面的效率会有点慢,我们可以优化一下

func isPowerOfThree(n int) bool {
    if n < 1 {
        return false
    }
    s := strconv.FormatInt(int64(n), 3)
    //直接用字符串来判断,开头为一,其他都为0
    return s[0:1] == "1" && strings.Count(s, "0") == len(s)-1
}

执行用时:28 ms, 在所有 Go 提交中击败了75.09%的用户
内存消耗:6 MB, 在所有 Go 提交中击败了100.00%的用户

还有一种适用于该题的数学解法,在int范围内的3的幂只有19个,分别是

1, 3, 9, 45, 99, 111, 153, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147, 531441, 1594323, 4782969, 14348907, 43046721,
129140163, 387420489, 1162261467

最大的第19个为1162261467
因为 3 是质数,所以 3^19 的除数只有 33,31, …3 ^19,因此我们只需要将 3^19 除以 n。若余数为 0 意味着 n 是 3^19的除数,因此是 3 的幂。

复杂度
  • 时间复杂度:O(1)。
  • 空间复杂度:O(1)。
func isPowerOfThree(n int) bool {
  return n > 0 && 1162261467 % n == 0;
}

执行用时:24 ms, 在所有 Go 提交中击败了84.39%的用户
内存消耗:6.1 MB, 在所有 Go 提交中击败了29.51%的用户

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容