4. 丑数 II

21 篇文章 0 订阅
11 篇文章 0 订阅

思路

设计一个算法,找出只含素因子235 的第 n 小的数。
符合条件的数如:1, 2, 3, 4, 5, 6, 8, 9, 10, 12...
注意事项
    我们可以认为1也是一个丑数
样例
    如果n = 9, 返回 10
分析
    1是最小丑数
    需要找到第n小的丑数,他的因子只含有235(可以重复)
    每下一个数字可能是前面序列的数字的235倍, 那我们从1开始
    f[1] = 1
    f[2] = min(f[1] * 2, f[1] * 3, f[1] * 5) = f[1] * 2 = 2
    f[3] = min(f[1] * 3, f[2] * 2) = f[1] * 3
    f[4] = min(f[1] * 5, f[2] * 2, f[3] * 2) = f[2] * 2 = 4
    f[5] = min(f[1] * 5, f[2] * 3, f[3] * 2) = f[1] * 5 = 5
    f[6] = min(f[2] * 3, f[3] * 2) = f[2] * 3 = 6
    f[7] = min(f[2] * 5, f[3] * 3, f[4] * 2) = f[4] * 2 = 8
    我们可以看到
    i2 代表还可以乘2的下标
    i3 代表还可以乘3的下标
    i5 代表还可以乘5的下标
    f[i] = min(f[i2] * 2, f[i3] * 3, f[i5] * 5)
    #####################
    重新模拟一边  f[i] = min(f[i2] * 2, f[i3] * 3, f[i5] * 5)
    i2, i3, i5 =1, 1, 1    f[1] = 1
    i2, i3, i5 =1, 1, 1    f[2] =  min(f[1] * 2, f[1] * 3, f[1] * 5) = min(2, 3, 5) = 2        i2 = 2
    i2, i3, i5 =2, 1, 1    f[3] =  min(f[2] * 2, f[1] * 3, f[1] * 5) = min(4, 3, 5) = 3        i3 = 2
    i2, i3, i5 =2, 2, 1    f[4] =  min(f[2] * 2, f[2] * 3, f[1] * 5) = min(4, 6, 5) = 4        i2 = 3
    i2, i3, i5 =3, 2, 1    f[5] =  min(f[3] * 2, f[2] * 3, f[1] * 5) = min(6, 6, 5) = 5        i5 = 2
    i2, i3, i5 =3, 2, 2    f[6] =  min(f[3] * 2, f[2] * 3, f[2] * 5) = min(6, 6, 10) = 6       i2, i3 = 4, 3
    i2, i3, i5 =4, 3, 2    f[7] =  min(f[4] * 2, f[3] * 3, f[2] * 5) = min(8, 9, 10) = 8       i2 = 5
    i2, i3, i5 =5, 3, 2    f[7] =  min(f[5] * 2, f[3] * 3, f[2] * 5) = min(10, 9, 10) = 9      i3 = 4
    ···········
    于是我们得到结论
    f[i] = min(f[i2] * 2, f[i3] * 3, f[i5] * 5)

Python

class Solution:
    """
    @param n: An integer
    @return: the nth prime number as description.
    """

    def nthUglyNumber(self, n):
        # write your code here
        i2, i3, i5 = 1, 1, 1
        f = [0 for x in range(n + 1)]
        f[1] = 1
        if n < 1:
            return -1
        for i in range(2, n + 1):
            f[i] = min(f[i2] * 2, f[i3] * 3, f[i5] * 5)
            if f[i] == f[i2] * 2:
                i2 += 1
            if f[i] == f[i3] * 3:
                i3 += 1
            if f[i] == f[i5] * 5:
                i5 += 1
        return f[n]


if __name__ == "__main__":
    s = Solution()
    a = 9
    print(s.nthUglyNumber(a))

Go

package main

import (
    "fmt"
)

/**
 * @param n: An integer
 * @return: the nth prime number as description.
 */
func nthUglyNumber(n int) int {
    // write your code here
    var i2, i3, i5 int
    var f []int
    i2, i3, i5 = 1, 1, 1
    f = make([]int, n+1)
    f[1] = 1
    for i := 2; i <= n; i++ {
        f[i] = min(min(f[i2]*2, f[i3]*3), f[i5]*5)
        if f[i] == f[i2]*2 {
            i2++
        }
        if f[i] == f[i3]*3 {
            i3++
        }
        if f[i] == f[i5]*5 {
            i5++
        }
    }
    return f[n]
}

func min(x int, y int) int {
    if x <= y {
        return x
    }
    return y
}

func main() {
    fmt.Println(nthUglyNumber(9))
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值