利用堆排序很容易进行查找javascript
质数又称素数。一个大于1的天然数,除了1和它自身外,不能被其余天然数整除的数叫作质数;不然称为合数。
质因数(素因数或质因子)在数论里是指能整除给定正整数的质数。除了1之外,两个没有其余共同质因子的正整数称为互质。由于1没有质因子,1与任何正整数(包括1自己)都是互质
把只包含质因子二、3和5的数称做丑数(Ugly Number)。例如六、8都是丑数,但7.14不是,由于它们包含质因子7。 习惯上咱们把1当作是第一个丑数java
class Ugly { constructor (n, primes) { this.n = n this.primes = new Heap(primes) } getAll () { // 超级丑数列表 let res = [1] let i = 2 let primes = this.primes // 不知道上限用while循环 while (res.length < this.n) { let arr = Ugly.getPrimies(i) let k = 0 let l = arr.length for (; k < l; k++) { if (!primes.find(arr[k])) { break } } // k===l有两种状况,1.压根没有质因数,2.质因数都在指定列表中 if (k === l) { if (l === 0) { if (primes.find(i)) { res.push(i) } } else { res.push(i) } } i++ } // 返回丑数数组 return res[this.n - 1] } // 计算指定正整数n的质因数 static getPrimies (n) { let prime = (n) => { let arr = [] for (let i = 2; i < n / 2 + 1; i++) { // 求质数利用递归,由于返回的是一个arr数组,当数组为空时说明是质数 if (n % i === 0 && !prime(i).length) { arr.push(i) } } return arr } return prime(n) } } class Heap { constructor (arr) { this.data = arr this.max = arr.length this.sort() } sort () { let iArr = this.data let n = iArr.length if (n <= 1) { return iArr } else { // 循环是为了遍历每个可能要调整的节点,maxHeapify内部递归是为了回复被破坏的堆 for (let i = Math.floor(n / 2); i >= 0; i--) { Heap.maxHeapify(iArr, i, n) } return iArr } } find (val, i = 0) { let arr = this.data if (val > arr[i] || i > this.max) { return false } else if (val === arr[i]) { return val } else { return this.find(val, i * 2 + 1) || this.find(val, i * 2 + 2) } } static swap (arr, a, b) { if (a === b) { return '' } // 交换 let c = arr[a] arr[a] = arr[b] arr[b] = c } // 构建最大堆 static maxHeapify (Arr, i, size) { // 左节点 let l = i * 2 + 1 // 右节点 let r = i * 2 + 2 let largest = i // 父节点和左节点l做比较获取最大 if (l <= size && Arr[l] > Arr[largest]) { largest = l } // 右节点额最大值比较 if (r <= size && Arr[r] > Arr[largest]) { largest = r } if (largest !== i) { Heap.swap(Arr, i, largest) Heap.maxHeapify(Arr, largest, size) } } } export default Ugly export { Heap }