zoukankan      html  css  js  c++  java
  • 超级丑数--用堆查找解决

    利用堆排序很容易进行查找


    质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数。
    质因数(素因数或质因子)在数论里是指能整除给定正整数的质数。除了1以外,两个没有其他共同质因子的正整数称为互质。因为1没有质因子,1与任何正整数(包括1本身)都是互质
    把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但7.14不是,因为它们包含质因子7。 习惯上我们把1当做是第一个丑数

    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
    }
    
    
  • 相关阅读:
    C#项目打包,并自动安装SQL数据库(转)
    [转]将List对象列表转换成JSON格式的类
    查找算法集:顺序查找、二分查找、插值查找、动态查找(数组实现、链表实现)
    C#编码好习惯
    数据库构思与设计规范
    ASP.NET下母版页和内容页中的事件发生顺序整理
    记录要点
    div挡住select的5种方法
    html源码获取方法
    TransactionScope 分布式事务
  • 原文地址:https://www.cnblogs.com/ygjzs/p/12236809.html
Copyright © 2011-2022 走看看