数学-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%的用户

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容