0000中等 LeetCode264. 丑数 II NC79 丑数

264. 丑数 II

描述

给你一个整数 n ,请你找出并返回第 n 个 丑数 。
丑数 就是只包含质因数 2、3 和/或 5 的正整数。

分析

一个丑数是由2,3,5中的一个与前面已经得到的一个丑数相乘得来。
任何一个丑数与2,3,5都会得到一个新的丑数。
如何得到下一个丑数:
2,3,5同时遍历已经得到的丑数,谁与丑数的乘积小,这个乘积便是下一个丑数,同时这个质数在丑数上的遍历前进1,因为下一个丑数更大。

在这里插入图片描述

一个丑数其实就是若干个2、3和5相乘而得到的。也就说第n个丑数的因子在前面的丑数中肯定出现过。那么第n个丑数的产生由前哪个丑数来决定的呢?我们可以肯定的是,是由前面某的一个丑数乘以2,3或者5得到的。假设现在有一个已经排好序的丑数数组,其中最大的丑数M排在数组的最后一个位置。如果我们将这所有的丑数都乘以2,那么就会得到很多丑数,这些丑数有的比M大,有的比M小。我们假设第一个比M大的数为M2。同理,我们可以将所有的丑数乘以3和5,得到第一个比M大的数称为M3和M5。这样M2,M3和M5都比M大。取这三者之中的最小者,就是下一个丑数了。
原文链接:https://blog.csdn.net/u010912383/article/details/51940940

官方题解里提到的三个指针p2,p3,p5,但是没有说明其含义,实际上pi的含义是有资格同i相乘的最小丑数的位置。这里资格指的是:如果一个丑数nums[pi]通过乘以i可以得到下一个丑数,那么这个丑数nums[pi]就永远失去了同i相乘的资格(没有必要再乘了),我们把pi++让nums[pi]指向下一个丑数即可。
不懂的话举例说明:
一开始,丑数只有{1},1可以同2,3,5相乘,取最小的1×2=2添加到丑数序列中。
现在丑数中有{1,2},在上一步中,1已经同2相乘过了,所以今后没必要再比较1×2了,我们说1失去了同2相乘的资格。
现在1有与3,5相乘的资格,2有与2,3,5相乘的资格,但是2×3和2×5是没必要比较的,因为有比它更小的1可以同3,5相乘,所以我们只需要比较1×3,1×5,2×2。
依此类推,每次我们都分别比较有资格同2,3,5相乘的最小丑数,选择最小的那个作为下一个丑数,假设选择到的这个丑数是同i(i=2,3,5)相乘得到的,所以它失去了同i相乘的资格,把对应的pi++,让pi指向下一个丑数即可。
作者:zzxn
链接:https://leetcode-cn.com/problems/ugly-number-ii/solution/san-zhi-zhen-fang-fa-de-li-jie-fang-shi-by-zzxn/

先建立长度为N的数组uglyNum,以便存储求来的丑数。按照程序的顺序来求, 初始值uglyNum[0] =
1;三路索引初始均指向第一个数。三个索引相互独立 第一次比较: 12 13
三个中的最小值为2,所以下一个丑数取2,那么数组中的值为1、2。mutil2++,指向数组中下一个元素:2 15 第二次比较: 22
13 三个数中的最小值为3,所以下一个丑数取3,那么数组中的值为1、2、3。mutil3++,指向数组中的下一个元素:2 15
第三次比较: 22 23
三个数中的最小值为4,所以下一个丑数取4,那么数组中的值为1、2、3、4。mutil2++,指向数组中的下一个元素:3 1*5 依此…
原文链接:https://blog.csdn.net/qq_34250494/article/details/88989109

public class Solution {
    public int GetUglyNumber_Solution(int index) {
        if(index < 2){
            return index;
        }
        int[] arr = new int[index];
        int two = 0, thr = 0, fiv = 0;
        arr[0] = 1;
        for(int i = 1; i < index; i++){
            int tmp = Math.min(arr[two]*2,Math.min(arr[fiv]*5,arr[thr]*3));
            if(tmp == arr[two]*2) two++;
            if(tmp == arr[fiv]*5) fiv++;
            if(tmp == arr[thr]*3) thr++;
            arr[i] = tmp;
        }
        return arr[index-1];
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值