leetcode - 264. Ugly Number II

算法系列博客之Dynamic Programming

本篇博客将运用动态规划的思想来解决leetcode上264号问题


问题描述:

Write a program to find the n-th ugly number.
Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers.
Note that 1 is typically treated as an ugly number, and n does not exceed 1690.

特意挑出此题发博的原因在于它较之前所写DP问题有明显两处不同
      状态转移不依赖于一个给定的特征列表
      如果把每个丑数视为一个状态,则它并不是简单的依赖于固定前一项或者前几项

根据基本的合数的质因数分解可以明白这样一个简单的道理
仅需要将前面的丑数简单的乘以2/3/5即可构造出后面的丑数
关键在于丑数的选择以及2/3/5的选择,得出的结果还要做到不重不漏

事实上,考虑它只能通过乘以2/3/5,且每个数最多只能把这三个数各乘一次
问题就可以看作,新的状态依赖于前面的某三个状态,并且这三个状态都一定会顺次后移
不妨用三个数state[3]来记录2/3/5分别对应依赖于哪三个状态
然后用这三个状态构造出三个丑数(即三个新状态),选择最小的,并将其对应状态顺移

显然5对应状态一定是最靠前的,再前面的状态无需保留
其次还需注意可能两个或者三个状态构造出的三个新状态都相同,这种情况三个状态都应该顺移
至此,可以很清晰的实现代码逻辑结构如下

class Solution(object):
    def nthUglyNumber(self, n):
        if n < 4: return n
        cur = 3
        state = [1, 1, 0]
        numsqueue = [1, 2, 3]
        while cur < n:
            new1 = numsqueue[state[0]] * 2
            new2 = numsqueue[state[1]] * 3
            new3 = numsqueue[0] * 5
            newnum = min(min(new1, new2), new3)
            if newnum == new1:
                state[0] += 1
            if newnum == new2:
                state[1] += 1
            if newnum == new3:
                numsqueue.pop(0)
                state[0] -= 1
                state[1] -= 1
            numsqueue.append(newnum)
            cur += 1
        return numsqueue[-1]

时间复杂度分析,整个算法只需要n次循环,每次循环执行常数条指令,因而O(n)
空间复杂度分析,使用了一个变量一个3元素列表和一个变长列表,而变长列表规模分析起来比较困难,但一定不会超过n,因而不妨简单归为O(n), 它也仍然是一个高效的算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值