当前位置: 首页 > article >正文

Day20:丑数

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

说明:丑数是只包含质因数 2、3 和/或 5 的正整数;1 是丑数。

示例 1:

输入: n = 10
输出: 12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。 

 LCR 168. 丑数 - 力扣(LeetCode)

 首先使用最小堆来做这个题目,因为2,3,5是丑数,那么2x,3x,5x也是丑数,我们使用一个set去重就行了。排序的话堆会帮我们排序排好的。

第一遍的代码生成丑数的方式不对:

class Solution {
    public int nthUglyNumber(int n) {
        int ugly = 0;
        if(n == 1){
            return 1;
        }
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();
        HashSet<Integer> hashSet = new HashSet<>();
        for(int i = 1; i < n; i++){
            hashSet.add(2*i);
            hashSet.add(3*i);
            hashSet.add(5*i);
        }

        for(Integer i : hashSet){
            minHeap.offer(i);
        }

        int index = 0;
        for (Integer i : minHeap) {
            if (index == n) {
                ugly = i;
                break;
            }
            index++;
        }

        return ugly;
    }
}

比如14加进去了,但是14不是丑数。

应该这样,把1加进去,然后,1的2,3,5倍加进去,然后1出队,就这样一直出队并把堆顶的2,3,5倍加入,用一个Set接收,如果成功接收,index++,等index等于n的时候,返回。

第二版代码符合逻辑,但是在n过大的时候超出时间限制:

class Solution {
    public int nthUglyNumber(int n) {
        int index = 0;
        int result = 0;
        if(n == 1){
            return 1;
        }
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();
        HashSet<Integer> hashSet = new HashSet<>();
       
        minHeap.offer(1);
        while(!minHeap.isEmpty()){
            int top = minHeap.poll();
            minHeap.offer(top*2);
            minHeap.offer(top*3);
            minHeap.offer(top*5);

            if(hashSet.add(top)){
                index++;
            }

            if(index == n){
                result = top;
                break;
            }
        }
        return result;
    }
}

想要再优化,只能上动态规划了。

dp[i] 代表第i个丑数,dp[1] = 1; 设置三个指针p2,p3,p5用来代表当前元素乘以几,dp[i] = min(dp[p2]*2,dp[p3]*3,dp[p5]*5),如果使用了指针,就得++;

最后return dp[n];

class Solution {
    public int nthUglyNumber(int n) {
       int[] dp = new int[n+1];
       dp[1] = 1;
       int p2 = 1;
       int p3 = 1;
       int p5 = 1;
       for(int i = 2;i < n+1; i++){
          dp[i] = Math.min(Math.min(dp[p2]*2,dp[p3]*3),dp[p5]*5);
          if(dp[i] == dp[p2]*2){
            p2++;
          }

          if(dp[i] == dp[p3]*3){
            p3++;
          }

          if(dp[i] == dp[p5]*5){
            p5++;
          }
       }
       return dp[n];
    }
}

原文地址:https://blog.csdn.net/m0_65150762/article/details/146383514
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/592415.html

相关文章:

  • 解码软件需求的三个维度:从满足基础到创造惊喜
  • dart学习记录3(函数)
  • 蓝桥杯备考----》快速幂算法之乘方
  • 大模型开发(六):LoRA项目——新媒体评论智能分类与信息抽取系统
  • 力扣100二刷——图论、回溯
  • electron框架(1.0)认识electron和基础创建
  • 使用PyMongo操作MongoDB(一)
  • MR-Flink-Spark任务提交-常用命令
  • 物联网的数据传输与处理!
  • [GHCTF 2025]真会布置栈吗?
  • WebGL学习2
  • 【红黑树】—— 我与C++的不解之缘(二十五)
  • Windows 图形显示驱动开发-WDDM 3.0功能- 硬件翻转队列(四)
  • K-均值聚类
  • Python 实现高效的实体扩展算法
  • 正点原子[第三期]Arm(iMX6U)Linux移植学习笔记-6.2uboot启动流程-lowlevel_init,s_init,_main函数执行
  • Windows 11右键菜单栏如何修改为Windows 10风格【完整教程】以及如何恢复Win11菜单栏风格
  • 技术改变生活:探索新科技的力量与影响
  • element-plus中Dropdown下拉菜单组件的使用
  • 论文解读:含可靠置信度的视频超分辨显微成像(频域卷积+贝叶斯深度学习)