Leetcode:264. Ugly Number II

描述

Write a program to find the n-th ugly number.

Ugly numbers are positive numbers whose prime factors only include 2, 3, 5.

Example:

Input: n = 10
Output: 12
Explanation: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers.
找出第n个丑数

这道题是之前那道Ugly Number 丑陋数的延伸,这里让我们找到第n个丑陋数,还好题目中给了很多提示,基本上相当于告诉我们解法了,根据提示中的信息,我们知道丑陋数序列可以拆分为下面3个子列表:

(1) 1x2, 2x2, 2x2, 3x2, 3x2, 4x2, 5x2…
(2) 1x3, 1x3, 2x3, 2x3, 2x3, 3x3, 3x3…
(3) 1x5, 1x5, 1x5, 1x5, 2x5, 2x5, 2x5…

[1] index2*2系列
[2] index3*3 系列
[3] index5*5 系列
链表合并系列, 三个连标合并系列,
这个过程就好像是合并三个链表这种情况,

代码来源

public int nthUglyNumber(int n) {

        int[] uglyNumbers = new int[n];
        uglyNumbers[0] = 1;
//      System.out.println("uglyNumbers[0]:1");

        int idx2 = 0;
        int idx3 = 0;
        int idx5 = 0;

        int counter = 1;
        while (counter < n) {

//          System.out.println("-----------");
//          System.out.println("idx2:" + idx2 + ";ugly[idx2]:" + uglyNumbers[idx2]);
//          System.out.println("idx3:" + idx3 + ";ugly[idx3]:" + uglyNumbers[idx3]);
//          System.out.println("idx5:" + idx5 + ";ugly[idx5]:" + uglyNumbers[idx5]);
//          System.out.println("idx2:" + idx2 + ";idx3:" + idx3 + ";idx5:" + idx5);

            int min = minOf(
                uglyNumbers[idx2] * 2, 
                uglyNumbers[idx3] * 3, 
                uglyNumbers[idx5] * 5);

            if (min == uglyNumbers[idx2] * 2) {
//              System.out.println("min==ugly[idx2]*2:" + uglyNumbers[idx2] * 2);
//              System.out.println("idx2:" + idx2 + "→" + (idx2 + 1));
                idx2++;
            }

            if (min == uglyNumbers[idx3] * 3) {
//              System.out.println("min==ugly[idx3]*3:" + uglyNumbers[idx3] * 3);
//              System.out.println("idx3:" + idx3 + "→" + (idx3 + 1));
                idx3++;
            }

            if (min == uglyNumbers[idx5] * 5) {
//              System.out.println("min==ugly[idx5]*5:" + uglyNumbers[idx5] * 5);
//              System.out.println("idx5:" + idx5 + "→" + (idx5 + 1));
                idx5++;
            }

            uglyNumbers[counter] = min;
//          System.out.println("uglyNumbers[" + counter + "]:" + min);
            counter++;
        }

//      System.out.println("-----------");
//      System.out.println("return:" + uglyNumbers[n - 1]);

        return uglyNumbers[n - 1];
    }

    /**
     * 求三个数字中最小的数字
     * @param a 数字a
     * @param b 数字b
     * @param c 数字c
     * @return a、b、c中最小的数字
     */
    private int minOf(int a, int b, int c) {
        int temp = a < b ? a : b;
        return temp < c ? temp : c; 
    }

简化版本代码

“`
class Solution {
public int nthUglyNumber(int n) {
//后验证的方法解决问题
if(n<=0) return 0;
if(n==1) return 1;
int [] result= new int [n];
result[0] =1;
// pointers for 2, 3, 5

int i2=0, i3=0,i5=0;
int factor2 =2, factor3 =3, factor5= 5;
    for(int i =1;i<n;++i){
    int min = Math.min(Math.min(factor2,factor3), factor5);
    result[i] = min;
    //更新最后一个序列的数据,
    if(result[i] == factor2)
    //在这里result[++index]代表的是上一个数据的值
        factor2 = result[++i2] *2;
    if(result[i] ==factor3)
        factor3 = result[++i3] *3;
    if(result[i]==factor5)
        factor5 = result[++i5] *5;
}
    return result[n-1];

}

initialize
ugly[] = | 1 |
i2 = i3 = i5 = 0;

First iteration
ugly[1] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(2, 3, 5)
= 2
ugly[] = | 1 | 2 |
i2 = 1, i3 = i5 = 0 (i2 got incremented )

Second iteration
ugly[2] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(4, 3, 5)
= 3
ugly[] = | 1 | 2 | 3 |
i2 = 1, i3 = 1, i5 = 0 (i3 got incremented )

Third iteration
ugly[3] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(4, 6, 5)
= 4
ugly[] = | 1 | 2 | 3 | 4 |
i2 = 2, i3 = 1, i5 = 0 (i2 got incremented )

Fourth iteration
ugly[4] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(6, 6, 5)
= 5
ugly[] = | 1 | 2 | 3 | 4 | 5 |
i2 = 2, i3 = 1, i5 = 1 (i5 got incremented )

Fifth iteration
ugly[4] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(6, 6, 10)
= 6
ugly[] = | 1 | 2 | 3 | 4 | 5 | 6 |
i2 = 3, i3 = 2, i5 = 1 (i2 and i3 got incremented )

Will continue same way till I < 150

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值