持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情
题目(Ugly Number)
链接:https://leetcode-cn.com/problems/ugly-number
解决数:1060
通过率:50.9%
标签:数学
相关公司:adobe amazon google
丑数 就是只包含质因数 2、3 和 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
思路
- 没啥思路…… 把这个数不断除?
- 不对可以求余判断,如果有余数,说明不能除了,否则可以继续往下除
- 以此类推,把2,3,5都过一遍,最后剩下的如果不是1,那就不是丑数
- 这样有没有可优化的地方?
- 可以被5除的前提是,个位是0或者5,可以根据个位来优先判断
- 再根据是否是偶数来判断能否继续被2除
- 再根据多位相加,判断是否能被3除,若可以,则进行
注意细节
- 这里可能是负整数,需要排除
- 关于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
};