Skip to content

Commit f52fc35

Browse files
author
wangpeng
committed
feat(MEDIUM): add _264_nthUglyNumber
1 parent 7c89483 commit f52fc35

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package pp.arithmetic.leetcode;
2+
3+
import java.util.HashMap;
4+
5+
/**
6+
* Created by wangpeng on 2019-05-09.
7+
* 264. 丑数 II
8+
* <p>
9+
* 编写一个程序,找出第 n 个丑数。
10+
* <p>
11+
* 丑数就是只包含质因数 2, 3, 5 的正整数。
12+
* <p>
13+
* 示例:
14+
* <p>
15+
* 输入: n = 10
16+
* 输出: 12
17+
* 解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。
18+
* 说明:
19+
* <p>
20+
* 1 是丑数。
21+
* n 不超过1690。
22+
*
23+
* @see <a href="https://leetcode-cn.com/problems/ugly-number-ii/">ugly-number-ii</a>
24+
*/
25+
public class _264_nthUglyNumber {
26+
27+
public static void main(String[] args) {
28+
_264_nthUglyNumber nthUglyNumber = new _264_nthUglyNumber();
29+
System.out.println(nthUglyNumber.nthUglyNumber(10));
30+
long start = System.currentTimeMillis();
31+
System.out.println(nthUglyNumber.nthUglyNumber(431));
32+
long end = System.currentTimeMillis();
33+
System.out.println("循环法计算431耗时:" + (end - start));
34+
start = System.currentTimeMillis();
35+
System.out.println(nthUglyNumber.nthUglyNumber2(431));
36+
end = System.currentTimeMillis();
37+
System.out.println("三指针法计算431耗时:" + (end - start));
38+
}
39+
40+
/**
41+
* 解题二:动态规划+三指针
42+
* dp保存按序排列的丑数,三指针分别是*2,*3,*5,找出下一个丑数
43+
*
44+
* @param n
45+
* @return
46+
*/
47+
public int nthUglyNumber2(int n) {
48+
int[] dp = new int[n];
49+
dp[0] = 1;
50+
int i2 = 0, i3 = 0, i5 = 0;
51+
for (int i = 1; i < n; i++) {
52+
int min = Math.min(dp[i2] * 2, Math.min(dp[i3] * 3, dp[i5] * 5));
53+
if (min == dp[i2] * 2) i2++;
54+
if (min == dp[i3] * 3) i3++;
55+
if (min == dp[i5] * 5) i5++;
56+
dp[i] = min;
57+
}
58+
59+
return dp[n - 1];
60+
}
61+
62+
private HashMap<Integer, Boolean> map = new HashMap<>();
63+
64+
/**
65+
* 丑数求解过程:首先除2,直到不能整除为止,然后除5到不能整除为止,然后除3直到不能整除为止。
66+
* 最终判断剩余的数字是否为1,如果是1则为丑数,否则不是丑数
67+
* <p>
68+
* 解题思路:
69+
* 从1开始遍历,按丑数求解过程找出满足条件的第n个丑数(提交超时)
70+
* 思路优化(如何利用之前的计算)
71+
*
72+
* @param n
73+
* @return
74+
*/
75+
public int nthUglyNumber(int n) {
76+
map.put(1, true);
77+
int uglyCount = 1;
78+
int retVal = 1;
79+
for (int i = 2; i < Integer.MAX_VALUE; i++) {
80+
if (uglyCount >= n) {
81+
break;
82+
}
83+
boolean isUgly = isUglyNumber(i);
84+
if (isUgly) {
85+
map.put(i, true);
86+
uglyCount++;
87+
retVal = i;
88+
}
89+
}
90+
91+
return retVal;
92+
}
93+
94+
private boolean isUglyNumber(int num) {
95+
while (num % 2 == 0) {
96+
num = num / 2;
97+
if (map.containsKey(num)) return true;
98+
}
99+
while (num % 5 == 0) {
100+
num = num / 5;
101+
if (map.containsKey(num)) return true;
102+
}
103+
while (num % 3 == 0) {
104+
num = num / 3;
105+
if (map.containsKey(num)) return true;
106+
}
107+
return num == 1;
108+
}
109+
}

0 commit comments

Comments
 (0)