[路飞]_Leetcode 1201. 丑数 III

115 阅读2分钟

「携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情

今天我们来做一下leetcode上面的一道比较经典的题目

题目链接在这里 1201. 丑数 III

题意

image.png

这道题可以说和第878题基本一模一样878. 第 N 个神奇数字,建议做这道题之前可以先看下前面的那道题。

好了,话题回到这道题目上,这道题说给了我们四个数字,第一个数字n代表问题,想让我们求第n个丑数,那么什么是丑数呢? 跟随题意,我们知道了,丑数就是可以被a b c中的若干个数字整除的数字,也就是因子中有abc的数字,然后,从大到小来数,让我们求第n个丑数。

思路

可以发现,如果直接从前往后递推来算第n个丑数的话,无疑会感觉有些困难。那么,我们不妨换个思路。

  • 假设现在已经找到了第n个丑数x的位置,
    • 那么,第n个丑数x及它之前一共就有n个丑数,也就是1~x的范围内有n个丑数
    • 所以,原题目求第n个丑数x的问题,就转化成了 存在一个数字x,在1-x中有n个丑数,求这个数字
      • 根据题目的数据范围,问题转变为:在2*10^9的范围中,存在一个数字x使得1~x中有n个丑数,求这个数字

      • 此时,观察原丑数序列,我们会发现如果根据其中的数字x是否满足在1~x中有n个丑数,那么,这个序列就变为了 0 0 0 0...0 1 ... 1

      • 所以,原问题也就进一步转化为,在01序列中求第一个1的问题。那么,顺理成章的,我们就想到了使用二分进行求解。

    • 另外,求一个数字x在1~x范围有多少个丑数时,也就是有多少个数可以被a或b或c整除时,需要注意
      • 被a整除的数字有 x/a|0个 被a整除的数字有 x/b|0个 被a整除的数字有 x/c|0个
      • 这里面把同时被ab bc ac整除是数字算重复了,所以需要减去这部分
      • 减掉这部分之后,同时被abc整除的数字也被减掉了,这部分需要补上去

image.png

代码实现

根据上面的思路分析,最终实现代码如下

image.png

结束语

如果有更好的分析思路,欢迎大家在评论区发表看法!⛄