【Leetcode】264. Ugly Number II ,丑数总结

你猜 阅读:353 2022-03-12 16:24:50 评论:0
本文章主要介绍了【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. For example, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers.

Note that 1 is typically treated as an ugly number, and n does not exceed 1690.

Show Hint
Hint:

The naive approach is to call isUgly for every number until you reach the nth one. Most numbers are not ugly. Try to focus your effort on generating only the ugly ones.

An ugly number must be multiplied by either 2, 3, or 5 from a smaller ugly number.

The key is how to maintain the order of the ugly numbers. Try a similar approach of merging from three sorted lists: L1, L2, and L3.

Assume you have Uk, the kth ugly number. Then Uk+1 must be Min(L1 * 2, L2 * 3, L3 * 5).

思路

不能够依次去判断每个数是不是丑数,这样时间复杂度会特别高。所以只能根据丑数来求下一个丑数。

我们知道丑数都是由已有的丑数乘以2、3、5得到的,所以核心目标就变成了找到下一个丑数,即从当前丑数里找到一个数,乘以2或3或5之后刚好大于当前最大丑数。于是,我们可以维护三个下标,分别记录A、B、C三个数,这三个数有这样的特点:

A*2 > maxUgly, B*3 > maxUgly, C*5 > maxUgly 

然后我们再比较A*2, B*3和C*5哪个最小,这样它就是当前最大丑数了!

另外,每次求得当前最大丑数后,还需要更新A、B、C的下标,利用while循环就可以更新了。

代码

public class Solution { 
    public int min(int a, int b, int c) { 
        int t = a < b ? a : b; 
        return t < c ? t : c; 
    } 
 
    public int nthUglyNumber(int n) { 
        if(n <= 0) return -1; 
        //创建一个大小为n的数组存储前n个丑数 
        int[] u = new int[n]; 
 
        u[0] = 1; 
		//创建三个下标分别记录第一个乘以2、3、5的乘积大于当前最大的丑数的下标 
        int index2 = 0; 
        int index3 = 0; 
        int index5 = 0; 
         
		//记录当前丑数个数 
        int cur = 1; 
         
		//记录当前最大的丑数的下标 
        int maxIndex = 0; 
 
        while(cur < n) { 
        	//求丑数中乘以2、3、5中最小的数,作为下一个丑数 
            int m = min(u[index2] * 2, u[index3] * 3, u[index5] * 5); 
            u[cur++] = m; 
            //更新最大丑数下标 
            maxIndex++; 
            //更新index2,index3和index5,使得它们与2、3、5的乘积刚好大于当前最大丑数 
            while (u[index2]*2 <= u[maxIndex]) index2++; 
            while (u[index3]*3 <= u[maxIndex]) index3++; 
            while (u[index5]*5 <= u[maxIndex]) index5++; 
 
        } 
 
        return u[n-1]; 
    } 
}

标签:加密算法
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

我的关注

全民解析

搜索
排行榜
关注我们