「前端刷题」263.丑数(EASY)

99 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情

题目(Ugly Number)

链接:https://leetcode-cn.com/problems/ugly-number
解决数:1060
通过率:50.9%
标签:数学 
相关公司:adobe amazon google 

丑数 就是只包含质因数 23 和 5 的正整数。

给你一个整数 n ,请你判断 n 是否为 丑数 。如果是,返回 true ;否则,返回 false 。

 

示例 1:

输入: n = 6
输出: true
解释: 6 = 2 × 3

示例 2:

输入: n = 1
输出: true
解释: 1 没有质因数,因此它的全部质因数是 {2, 3, 5} 的空集。习惯上将其视作第一个丑数。

示例 3:

输入: n = 14
输出: false
解释: 14 不是丑数,因为它包含了另外一个质因数 7 。

 

提示:

  • -231 <= n <= 231 - 1

思路

  1. 没啥思路…… 把这个数不断除?
  2. 不对可以求余判断,如果有余数,说明不能除了,否则可以继续往下除
  3. 以此类推,把2,3,5都过一遍,最后剩下的如果不是1,那就不是丑数
  4. 这样有没有可优化的地方?
  5. 可以被5除的前提是,个位是0或者5,可以根据个位来优先判断
  6. 再根据是否是偶数来判断能否继续被2除
  7. 再根据多位相加,判断是否能被3除,若可以,则进行

注意细节

  1. 这里可能是负整数,需要排除
  2. 关于2 可以做位运算诶~

这里我做了实验——探究位运算和除法运算的效率

function caculateTime(callback) {
  const begin = new Date()
  callback()
  const end = new Date()
  return end.getTime() - begin.getTime()
}

// 位运算
const bitwise = () => {
  let cnt = 1000000
  while (cnt--) {
    const result = cnt >> 1
  }
}
// 除法运算
const division = () => {
  let cnt = 1000000
  while (cnt--) {
    const result = cnt / 2
  }
}

console.log('除法运算的测试:')
let sum2 = 0
for (let i = 0; i < 1000; i++) {
  sum2 += caculateTime(division)
}
console.log(sum2 + 'ms')

console.log('位运算的测试:')
let sum1 = 0
for (let i = 0; i < 1000; i++) {
  sum1 += caculateTime(bitwise)
}
console.log(sum1 + 'ms')

如果实际测试数据里面,因子2,3,5的占比为3:2:1,那么可以把if elseif判断顺序设置为 先判断2,再判断3,再判断5;若占比为1:2:3,那么先后顺序就改为5,3,2

代码

求余探底法

/**
 * @param {number} num
 * @return {boolean}
 */
var isUgly = function(num) {
    // 排除负数
    if (num < 1) return false
    // 为除数减少乘法运算
    const divisorMap = [1,2,3,6,5,10,15,30]
    while(num > 1) {
        let pos = 0
        if (num % 2 === 0) {
            pos++
        }
        if (num % 5 === 0) {
            pos = pos + 4
        }
        if (num % 3 === 0) {
            pos = pos + 2
        }
        if (pos > 0) {
            num = num / divisorMap[pos]
        } else {
            return false
        }
    }
    return true
};