zoukankan      html  css  js  c++  java
  • 264.丑数II

    题目

    给你一个整数 n ,请你找出并返回第 n 个 丑数 。

    丑数 就是只包含质因数 2、3 和/或 5 的正整数。

    示例 1:

    输入:n = 10
    输出:12
    解释:[1, 2, 3, 4, 5, 6, 8, 9, 10, 12] 是由前 10 个丑数组成的序列。
    示例 2:

    输入:n = 1
    输出:1
    解释:1 通常被视为丑数。

    暴力法

    求出int范围内所有的丑数,取第n个返回。

      public int nthUglyNumber(int n) {
            List<Integer> all=new ArrayList<>();
            for(long i=1;i<=Integer.MAX_VALUE;i*=2){
                for(long j=i;j<=Integer.MAX_VALUE;j*=3){
                    for(long k=j;k<=Integer.MAX_VALUE;k*=5){
                        all.add((int)k);
                    }
                }
            }
            Collections.sort(all);
            return all.get(n-1);
       }
    

    最小堆

    这里使用优先队列。队中初始有一个元素值为1,每次出队一个元素,将这个元素乘以2,3,5的值依次入队,第n个出队的元素值即为结果。

      public int nthUglyNumber(int n) {
            //类型设置为long防止溢出
            PriorityQueue<Long> q=new PriorityQueue<>();
            q.offer(1L);
            long count=0,num=0;
            while(count<n){
                num=q.poll();
                count++;
                q.offer(num*2);
                q.offer(num*3);
                q.offer(num*5);
                //去重
                while(q.peek()==num) q.poll();
            }
            return (int)num;
      }
    

    动态规划+三指针

    我们先模拟手写丑数的过程:
    1 打头,1 乘 2 1 乘 3 1 乘 5,现在是 {1,2,3,5}
    轮到 2,2 乘 2 2 乘 3 2 乘 5,现在是 {1,2,3,4,5,6,10}
    手写的过程和采用小顶堆的方法很像,但是怎么做到提前排序呢?

    小顶堆的方法是先存再排,dp 的方法则是先排再存
    我们设3个指针n2,n3,n5,代表的是第几个数的2倍、第几个数3倍、第几个数5倍
    动态方程:dp[i]=min(dp[n2]*2,dp[n3]*3,dp[n5]*5)
    小顶堆是一个元素出来然后存3个元素,动态规划则是标识3个元素,通过比较他们的2倍、3倍、5倍的大小,来一个一个存。

     public int nthUglyNumber(int n) {
            int[] dp=new int[n];
            dp[0]=1;
            int n2=0,n3=0,n5=0;
            for(int i=1;i<n;++i){
                dp[i]=Math.min(dp[n2]*2,Math.min(dp[n3]*3,dp[n5]*5));
                //每个判断都要用单独的if,不能用else if,因为可能有重复
                if(dp[i]==dp[n2]*2) n2++;
                if(dp[i]==dp[n3]*3) n3++;
                if(dp[i]==dp[n5]*5) n5++;
            }
            return dp[n-1];
      }
    

    原题:264.丑数II
    参考:暴力+优先队列(小顶堆)+动态规划(三指针)

  • 相关阅读:
    Verdi 看波形常用快捷操作
    Tensorflow系列——Saver的用法
    Verilog-分频器
    (原创)列主元Gauss消去法的通用程序
    冒泡排序算法
    ADC 与实际电压值的关系
    直流耦合 交流耦合 耦合
    当前不会命中断点,源代码与原始版本不同
    示波器触发
    在头文件#pragma comment(lib,"glaux.lib");编译器提示waring C4081: 应输入“newline“
  • 原文地址:https://www.cnblogs.com/Frank-Hong/p/14652669.html
Copyright © 2011-2022 走看看