leetcode 264.丑数

news2025/1/12 4:00:12

题目描述跳转去leetcode

给你一个整数 n ,请你找出并返回第 n 个 丑数 。
丑数 就是只包含质因数 2、3 和/或 5 的正整数。在这里插入图片描述

来源:leecode:https://leetcode.cn/problems/ugly-number-ii/

解法1, 动态规划

  1. 定义一个数组用来记录前n个丑数,最后返回数组中最后一个元素
class Solution {
    public int nthUglyNumber(int n) {
        // 创建
        int[] arr = new int[n];

        if(n<=6){
            return n;
        }else{
            int index = 6;
            int num = 7;
            int i = 0;
            //生成n个丑数
            while(index<n){
                if(i<6){
                    arr[i] = i+1;
                }else{
                    if(isUgly(num)){
                        arr[index] = num;
                        index++;
                    }
                    num++;
                }
               i++;
            }
        }
        return arr[n-1];

    }
    public boolean isUgly(int num) {
        if (num <= 0) {
            return false;
        }

        while (num % 2 == 0) {
            num /= 2;
        }
        while (num % 3 == 0) {
            num /= 3;
        }
        while (num % 5 == 0) {
            num /= 5;
        }

        return num == 1;
    }
}

提交后显示超出时间限制! 哦我的天在这里插入图片描述
2. 优化代码
方法:使用三个指针来分别记录当前需要乘以2、3、5的丑数的下标。每次取出三个指针对应位置的丑数乘以对应的因子,得到三个候选的下一个丑数,选择其中最小的作为下一个丑数加入数组中,并更新对应的指针和候选丑数。这样就可以避免重复计算和判断每一个数字是否为丑数,降低时间复杂度。
小结优化后的代码使用了动态规划来求解第 n 个丑数
动态规划的基本思想是将原问题拆分成不同的子问题,通过求解子问题的最优解来得到原问题的最优解。在这个算法中,我们定义一个数组 arr 来存储前 n 个丑数,其中 arr[0] = 1。
接下来,我们维护三个指针 i2、i3 和 i5,分别指向数组中乘以 2、3 和 5 后得到的下一个丑数。同时,我们维护三个变量 num2、num3 和 num5,表示乘以对应因子后得到的丑数。
我们从第 1 个丑数开始,枚举从已有的丑数中乘以 2、3、5 得到的最小值,并将其加入数组 arr 中。然后,在三个变量 num2、num3 和 num5 中更新对应丑数的值,直到得到第 n 个丑数为止。

class Solution {
    public int nthUglyNumber(int n) {
        // 创建
        int[] arr = new int[n];
        arr[0] = 1; // 第一个丑数是1

        int i2 = 0, i3 = 0, i5 = 0;
        int num2 = 2, num3 = 3, num5 = 5;

        for (int i = 1; i < n; i++) {
            // 下一个丑数是从已有的丑数中乘以2、3、5得到的最小值
            int next = Math.min(num2, Math.min(num3, num5));
            arr[i] = next;

            // 更新num2、num3、num5的值
            if (next == num2) {
                i2++;
                num2 = arr[i2] * 2;
            }
            if (next == num3) {
                i3++;
                num3 = arr[i3] * 3;
            }
            if (next == num5) {
                i5++;
                num5 = arr[i5] * 5;
            }
        }

        return arr[n - 1];
    }
}

最后结果可想而知,当然是通过啦!
在这里插入图片描述

解法2, 优先队列!(也是今天重点学习内容)

定义优先队列,用来计算当前最小丑数,最后返回队列中堆顶位置的元素
难点::如何计算后续的丑数,看了题解才知道因为set具有数据不重复的特点,所以要使用set来记录,前n个的丑数,下一个丑数,其实是从已有的丑数中乘以2、3、5得到的最小值,如果set中没有上述乘积结果值就把值add进去。

class Solution {
    public int nthUglyNumber(int n) {
        // 创建
        PriorityQueue<Integer> queue = new PriorityQueue<>();
        queue.offer(1); // 第一个丑数是1
        HashSet<Integer> set = new HashSet<>();
        set.add(1);

        int num = 1;
        int ugly = 1;
        int[] pers = new int[]{2, 3, 5};

        int u1 = -1, u2 = -1,u3 = -1;
        // 循环n次,找到第n个丑数
        for (int i = 1; i < n; i++) {
            // 取出当前最小丑数
            num = queue.poll();
            // 找下一个丑数, 下一个丑数是从已有的丑数中乘以2、3、5得到的最小值
            for(int per : pers){
                ugly = per*num;
                if(!set.contains(ugly)){
                    queue.offer(ugly);
                    set.add(ugly);
                }
            }

        }

        return queue.peek();
    }
}

提交结果错误,排查发现是因为数据溢出的原因,因此要将int类型改成long
在这里插入图片描述
以下是改了类型的代码

class Solution {
    public int nthUglyNumber(int n) {
        // 创建
        PriorityQueue<Long> queue = new PriorityQueue<>();
        queue.offer(1L); // 第一个丑数是1
        HashSet<Long> set = new HashSet<>();
        set.add(1L);

        Long num = 1L;
        long ugly = 1L;
        int[] pers = new int[]{2, 3, 5};

        // 循环n次,找到第n个丑数
        for (int i = 1; i < n; i++) {
            // 取出当前最小丑数
            num = queue.poll();
            // 找下一个丑数, 下一个丑数是从已有的丑数中乘以2、3、5得到的最小值
            for(int per : pers){
                ugly = per * num;
                if(!set.contains(ugly)){
                    queue.offer(ugly);
                    set.add(ugly);
                }
            }
        }

        return (int) queue.peek();
    }
}

点击执行~~~~, 糟糕,怎么又错了在这里插入图片描述
可能出现这种情况的原因:

  1. queue.peek() 返回的类型不是可以直接转换为 int 类型的基本数据类型。例如,如果 peek() 方法返回的是一个对象或字符串类型,使用 (int) 进行强制类型转换会报错。
  2. 如果队列为空,即不存在任何对象,queue.peek() 将返回 null。在将 null 强制转换成 int 时,会出现 java.lang.NullPointerException 空指针异常错误,导致编译错误。
    满足第一种情况:Long是一个对象类型
    所以最后的代码如下:
class Solution {
    public int nthUglyNumber(int n) {
        PriorityQueue<Long> queue = new PriorityQueue<>();
        queue.offer(1L); // 第一个丑数是1
        HashSet<Long> set = new HashSet<>();
        set.add(1L);

        Long num = 1L;
        long ugly = 1L;
        int[] pers = new int[]{2, 3, 5};

        // 循环n次,找到第n个丑数
        for (int i = 1; i < n; i++) {
            // 取出当前最小丑数
            num = queue.poll();
            // 找下一个丑数, 下一个丑数是从已有的丑数中乘以2、3、5得到的最小值
            for(int per : pers){
                ugly = per * num;
                if(!set.contains(ugly)){
                    queue.offer(ugly);
                    set.add(ugly);
                }
            }
        }

        long val = queue.peek();
        if (val > Integer.MAX_VALUE || val < Integer.MIN_VALUE) {
            throw new ArithmeticException("Value is out of range for an int.");
        }
        return (int) val;
    }
}

最后提交结果当然是成功的啦!在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/580218.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VMware Workstation 安装 AlmaLinux 9.2

VMware Workstation 安装 AlmaLinux 9.2 AlmaLinux 9.2 镜像下载AlmaLinux 9.2 安装创建新用户配置免密 sudo 到 root 用户配置 ssh key 登录挂载新磁盘 AlmaLinux 9.2 镜像下载 访问 https://mirrors.almalinux.org/isos.html 下载安装镜像&#xff0c; AlmaLinux 9.2 安装 …

K8s进阶7——Sysdig、Falco、审计日志

文章目录 一、分析容器系统调用&#xff1a;Sysdig1.1. 安装1.2 常用参数1.3 采集分析1.4 示例1.4.1 查看某进程系统调用事件1.4.2 查看建立TCP连接事件1.4.3 查看某目录下打开的文件描述符1.4.4 查看容器的系统调用 1.5 Chisels工具1.5.1 网络类1.5.2 硬盘类1.5.3 cpu类1.5.4 …

新型智慧园区解决方案之园区通行管理设计

智慧园区作为现代化城市化建设的重要组成部分&#xff0c;已经成为未来城市的重要发展方向。在智慧园区的建设中&#xff0c;通行管理是一个十分重要的问题。为了解决这一问题&#xff0c;我们需要进行一系列的设计和方案的制定。 一、园区交通规划设计 园区交通规划设计是通…

IIS总线介绍

IIS是飞利浦在1986年定义(1996年修订)的数字音频传输标准&#xff0c;用于数字音频数据在系统内器件之间传输&#xff0c;例如编解码器CODEC、DSP、数字输入/输出接口、ADC、DAC和数字滤波器等。其与IC无关联。 IIS总线的信号&#xff1a; BCLK&#xff0c;串行时钟也叫位时钟…

以太坊 – 部署智能合约到Ganache

目录 1. Ganache本地区块链 1.1 主界面 1.2 设置 2. 开发智能合约 2.1 初始化项目 2.2 添加package.json文件 2.3 添加智能合约源文件 2.4 编译项目 3. 部署智能合约到Ganache 3.1 更新配置文件 3.2 创建迁移脚本 3.3 执行迁移命令 1. Ganache本地区块链 首先启动…

springboot配置Swagger3.0

springboot配置Swagger3.0 1、pom加入依赖 我们创建一个SpringBoot项目&#xff0c;引入 swagger3 依赖 <dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>3.0.0</version>…

任正非:ChatGPT对我们的机会是什么,内部讲话实录!

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 我新建了人工智能中文站https://ai.weoknow.com 每天给大家更新可用的国内可用chatGPT资源 为感谢全国火花奖获奖者对于产业界及科学界做出的重大贡献&#xff0c;华为组织了与部分获奖老师与专家的座谈会。座谈会上&…

LeetCode.46. 全排列(回溯法入门)

写在前面&#xff1a; 题目链接&#xff1a;LeetCode.46. 全排列 编程语言&#xff1a;C 题目难度&#xff1a;中等 一、题目描述 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a…

【震撼GPT-4崛起!年薪60万工作被GPT-4取代,成本仅2千多,引发轰动!】

目录 福利&#xff1a;文末纯分享中文版CHAT GPT镜像&#xff0c;不存在魔法&#xff0c;纯分享免费使用 一、前言 1、GPT-4的表现&#xff0c;与一位6年工作经验的人类相当 2、GPT-4完成所有类型的任务都要比人类快得多&#xff01; 二、GPT-4当数据分析师&#xff0c;都…

聊一聊影响LCD屏背光效率的几个重要因素

前阶段&#xff0c;小白的一个朋友参加了一个面试。面试完和小白说到其技术面过程惨不忍睹。被提及原因时&#xff0c;主要还是因为面试者提出的问题&#xff0c;小白的朋友答复的可能不是很让面试官满意。出于好奇&#xff0c;小白问了问都存在哪些问题&#xff0c;其中一道便…

论文笔记:Graph neural networks: A review of methods and applications

1 GNN的设计pipeline 1.1 获取图结构 结构化场景 图结构在应用问题中是已知的 比如分子结构、物理系统非结构化场景 图结构在应用问题中是未知的 需要根据任务人为地建图 1.2 判断图的类型 & 尺寸 图的类型 有向图/无向图//异构图/同构图 图中的点和边类型是不是一样的…

Prometheus 简单介绍,部署

目录 Prometheus 介绍 功能介绍 Prometheus安装 安装介绍 prometheus.yml 文件介绍 prometheus实施安装 Prometheus常用命令参数有哪些 设置Prometheus-server开机自动启动 &#xff08;解释&#xff09; Prometheus简单启动页面介绍 node_exporte 是做什么的 安装n…

【个人笔记】真寻bot部署记录+远程postgreSQL访问+源码食用记录

安装 0. 系统配置 Centos v8.2 1. 安装 使用真寻bot https://github.com/zhenxun-org/zhenxun_bot-deploy bash <(curl -s -L https://raw.githubusercontent.com/zhenxun-org/zhenxun_bot-deploy/master/install.sh)选择1&#xff0c;安装go-cqhttp和zhenxun_bot&…

java boot项目读取yml配置信息

之前 我们讲过 boot的配置文件格式主要有三种 application.properties application.yml application.yaml 我们说推荐用 application.yml 其实从 xml 到 yml 都是要系统去读取他的配置信息 今天 我们就来写一下 在java中读取 yml的配置 这里 我在 yml中多加两个配置 代码如下…

LabView中顺序结构的使用

LabView中的顺序结构能够保证程序按照一定的顺序运行。LabView中的顺序结构分为平铺式顺序结构和层叠式顺序结构两种。 1 平铺式顺序结构 平铺式顺序结构包括一个或多个顺序执行的子程序框图&#xff0c;这种框图也被成为“帧”&#xff0c;程序按照帧为单位&#xff0c;以从…

MKS SERVO4257D 闭环步进电机_系列3 串口(RS485)指令说明

第1部分 产品介绍 MKS SERVO 28D/35D/42D/57D 系列闭环步进电机是创客基地为满足市场需求而自主研发的一款产品。具备脉冲接口和RS485/CAN串行接口&#xff0c;支持MODBUS-RTU通讯协议&#xff0c;内置高效FOC矢量算法&#xff0c;采用高精度编码器&#xff0c;通过位置反馈&am…

ATA-3000系列功率放大器在精密微流体控制中的典型应用

ATA-3000系列功率放大器在精密微流体控制中的典型应用 压电陶瓷精密微流体控制应用&#xff1a; 精密微流体控制在医药配比、遗传基因与生物工程、航空航天、军工国防等方面具有广泛的应用&#xff0c;特别是在大流量伺服阀先导控制领域&#xff0c;具有重要作用。随着压电陶瓷…

TPO69 01|Why Snakes Have Forked Tongues P5P6|阅读真题精读|17:50~19:35

17:00&#xff5e;17:50 吃饭 目录 P56 生词 段落大意 P5段落大意 P6段落大意 题目 【5】事实信息题|定位准确非常重要✅ 【6】事实信息题|定位准确非常重要✅ 【7】推理题|文章是否提及|不要过度推理 【8】修辞目的题|举例一般为了说明✅ 【9】句子插入题|in other words|同义…

SpringCloud Alibaba Seata

SpringCloud Alibaba Seata Seata 基础 先看一个问题&#xff0c;引出Seata 单机单库(多表)处理事务示意图 分布式微服务架构下的数据库事务示意图 3. 梳理上图 用户购买商品的业务逻辑。整个业务逻辑由3个微服务提供支持∶仓储服务∶对给定的商品扣除仓库/商品数量订单服务…

第10届蓝桥杯Scratch国赛真题集锦

编程题 第 1 题 问答题 捉迷藏之 题目说明 编程实现:小猫随机躲在6个按固定位置排列的前景角色任一个的后面,只露出一点点痕迹。具体要求: 1).添加任意1个背景,保留小猫角色,从角色库中挑选6个角色作为前景角色(小猫将躲在它们的后面) 2).6个前景角色按照两行三列的方式以固…