首页 > 其他分享 >力扣 264. 丑数 II [堆;多指针]

力扣 264. 丑数 II [堆;多指针]

时间:2023-01-26 20:55:08浏览次数:61  
标签:丑数 arr 12 10 int 力扣 II 序列

264. 丑数 II

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

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

示例 1:

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

示例 2:

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

提示:

  • 1 <= n <= 1690

解一:小顶堆

既然要按从小到大排序,就利用小顶堆(优先队列)的性质实现自动排序:

  1. 起始先将最小丑数1放入队列
  2. 每次从队列取出最小值x,然后将x所对应的丑数2x、3x5x进行入队。
  3. 对步骤2循环多次,第n次出队的值即是答案。

为了防止同一丑数多次进队,我们需要使用数据结构Set来记录入过队列的丑数。

查看代码

class Solution {
public:
    int nthUglyNumber(int n) {
        priority_queue<long,vector<long>,greater<long>> pque;//小顶堆
        int factors[3]={2,3,5};//三个因子
        unordered_set<long> flag;//是否加入过的标志位
        flag.insert(1L);
        pque.push(1L);
        int res=0;
        for(int i=0;i<n;i++){
            long cur=pque.top();
            res=(int)cur;
            pque.pop();
            for(int j=0;j<3;j++){//依次得到cur*当前因子
                long next=factors[j]*cur;
                if(!flag.count(next)){//判断是否加入
                    flag.insert(next);
                    pque.push(next);
                }
            }
        }
        return res;
    }
};

解二:多指针

来自这里

  • 由丑数*3所得的有序序列:1*3、2*3、3*3、4*3、5*3、6*3、8*3.…
  • 由丑数*5所得的有序序列:1*5、2*5、3*5、4*5、5*5、6*5、8*5.…

举个例子,假设我们需要求得[1,2,3…,10,12]丑数序列arr的最后一位,那么该序列可以看作以下三个有序序列归并而来:

  • 1*2,2*2,3*2…,10*2,12*2,将2提出,即arr*2
  • 1*3,2*3,3*3,…,10*3,12*3,将3提出,即arr*3
  • 1*5,2*5,3*5…,10*5,12*5,将5提出,即arr*5

因此我们可以使用三个指针来指向目标序列arr的某个下标,使用arr下标*质因数代表当前使用到三个有序序列中的哪一位,同时使用idx表示当前生成到arr哪一位丑数。

查看代码
class Solution {
public:
    int nthUglyNumber(int n) {
        int res[n];//按顺序记录丑数
        res[0]=1;//下标从0开始,第一个丑数是1
        int idx2,idx3,idx5;//三个序列的下标初始为0
        idx2=idx3=idx5=0;
        for(int i=1;i<n;i++){//依次计算第i+1个丑数
            long cur2=res[idx2]*2;//如果下标生成新的丑数
            long cur3=res[idx3]*3;
            long cur5=res[idx5]*5;
            long next=min(cur2,min(cur3,cur5));//选择最小的作为第i+1个丑数
            if(cur2==next)//因为next可能不止被一个序列覆盖,所以没有else
                idx2++;
            if(cur3==next)
                idx3++;
            if(cur5==next)
                idx5++;
            res[i]=(int)next;//记录第i+1个丑数
        }
    return res[n-1];//返回第n个丑数
    }
};

标签:丑数,arr,12,10,int,力扣,II,序列
From: https://www.cnblogs.com/fudanxi/p/17068050.html

相关文章

  • 力扣只出现一次的数字系列总结(C++)
    tags:LeetCodeC++DSA写在前面最近用到的异或运算越来越多了,而其中又以只出现一次的数字为经典题型,下面总结总结一下只出现一次的数字系列.代码均为C++.前置知识逻辑......
  • 【算法训练营day25】LeetCode216. 组合总和III LeetCode17. 电话号码的字母组合
    LeetCode216.组合总和III题目链接:216.组合总和III独上高楼,望尽天涯继续复健,一直在犯小的语法错误。慕然回首,灯火阑珊和昨天的题很像,主要区别在于递归返回条件和回溯......
  • 力扣101 对称二叉树
    题目:给你一个二叉树的根节点root,检查它是否轴对称。示例:输入:root=[1,2,2,3,4,4,3]输出:true思路:  对于二叉树是否对称,要比较的是根节点的左子树与......
  • UEFI EDKII 编程学习
    环境搭建部分第一步:下载EDK2​​https://sourceforge.net/projects/edk2/files/latest/download?source=files​​ 第二步:将下载的UDK2015.Complete.MyWorkSpace中的BaseTo......
  • 回文数-力扣
     回文数-力扣来源:力扣(LeetCode)链接:https://leetcode.cn/problems/palindrome-number著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。题目描述......
  • 二分查找的三种形式&两道力扣
    前言过年前刷Leetcode的时候遇到这样一道题目:354.俄罗斯套娃信封问题-力扣(Leetcode)其中使用patiencesorting这个算法的做法中,因为牌堆顶是有序数组,所以可以使用二分......
  • 【栈】LeetCode 772. 基本计算器 III
    题目链接772.基本计算器III思路与【栈】LeetCode227.基本计算器II完全相同代码classSolution{publicintcalculate(Strings){//定义运算符......
  • 力扣---1306. 跳跃游戏 III
    这里有一个非负整数数组 arr,你最开始位于该数组的起始下标 start 处。当你位于下标 i 处时,你可以跳到 i+arr[i]或者i-arr[i]。请你判断自己是否能够跳到对......
  • 552. Student Attendance Record II
    /***552.StudentAttendanceRecordII*https://leetcode.com/problems/student-attendance-record-ii/*Anattendancerecordforastudentcanberepresent......
  • 【栈】LeetCode 227. 基本计算器 II
    题目链接227.基本计算器II思路代码classSolution{//使用map维护一个运算符优先级//这里的优先级划分按照「数学」进行划分即可Map<Character,......