264. Ugly Number II [JavaScript]

一、解题思路

  第一种思:采用暴力求解,主要由于题目中说明了最多只有1690个“丑数”,那么可以先求出所有的“丑数”,再排序得到第n个“丑数”。

const nthUglyNumber = n => {
  const ans = []

  for (let a = 1; a < Number.MAX_SAFE_INTEGER; a *= 2) {
    for (let b = a; b < Number.MAX_SAFE_INTEGER; b *= 3) {
      for (let c = b; c < Number.MAX_SAFE_INTEGER; c *= 5) {
        ans.push(c)
      }
    }
  }

  ans.sort((a, b) => a - b)
  return ans[n - 1]
}

  上述代码虽然有一个三重循环,但是由于循环条件的特殊,时间复杂度并不会很高,它的时间复杂度主要由排序算法决定。

  那么可不可以只求出前n个“丑数”来解决这道题目?

  仔细观察上述方法输出的结果,你会发现每一个“丑数”都是在原有的基础上*2、3或者5推导出来的,那么就可以采用动态规划的方式解决这道题目,定义状态:

  dp[i]表示第i个丑数

  状态转移方程:

  dp[i] = Math.min(dp[x] * 2, dp[y] * 3, dp[z] * 5)

二、代码实现

const nthUglyNumber = n => {
  const ans = [1]
   
  let x = 0
  let y = 0
  let z = 0

  for (let i = 1; i < n; i++) {
    let xNext = ans[x] * 2
    let yNext = ans[y] * 3
    let zNext = ans[z] * 5
    const min = Math.min(xNext, yNext, zNext)
    if (min === xNext) {
      x++
    }
    if (min === yNext) {
      y++
    }
    if (min === zNext) {
      z++
    }
    ans[i] = min
  }

  return ans[n - 1]
}

  
  ----------------------------

关注「漫谈大前端」
不断成长为一名优秀的前端开发工程师

  ----------------------------
  

  您还可以在这些地方找到我:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值