Skip to content

Commit a00feb7

Browse files
committed
feat: add solutions to lc problem: No.0264
No.0264.Ugly Number II
1 parent 986f20a commit a00feb7

File tree

2 files changed

+265
-49
lines changed

2 files changed

+265
-49
lines changed

solution/0200-0299/0264.Ugly Number II/README.md

Lines changed: 139 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -40,22 +40,46 @@
4040

4141
<!-- 这里可写通用的实现逻辑 -->
4242

43-
动态规划法。
43+
**方法一:优先队列(最小堆)**
4444

45-
定义数组 dp,`dp[i - 1]` 表示第 i 个丑数,那么第 n 个丑数就是 `dp[n - 1]`。最小的丑数是 1,所以 `dp[0] = 1`
45+
初始时,将第一个丑数 $1$ 加入堆。每次取出堆顶元素 $x$,由于 $2x$, $3x$, $5x$ 也是丑数,因此将它们加入堆中。为了避免重复元素,可以用哈希表 $vis$ 去重
4646

47-
定义 3 个指针 p2,p3,p5,表示下一个丑数是当前指针指向的丑数乘以对应的质因数。初始时,三个指针的值都指向 0
47+
时间复杂度 $O(nlogn)$,空间复杂度 $O(n)$
4848

49-
`i∈[1,n)``dp[i] = min(dp[p2] * 2, dp[p3] * 3, dp[p5] * 5)`,然后分别比较 `dp[i]``dp[p2] * 2``dp[p3] * 3``dp[p5] * 5` 是否相等,若是,则对应的指针加 1。
49+
**方法二:动态规划**
5050

51-
最后返回 `dp[n - 1]` 即可。
51+
定义数组 $dp$,$dp[i-1]$ 表示第 $i$ 个丑数,那么第 $n$ 个丑数就是 $dp[n - 1]$。最小的丑数是 $1$,所以 $dp[0]=1$。
52+
53+
定义 $3$ 个指针 $p_2$,$p_3$,$p_5$,表示下一个丑数是当前指针指向的丑数乘以对应的质因数。初始时,三个指针的值都指向 $0$。
54+
55+
当 $i∈[1,n)$,$dp[i]=min(dp[p_2] \ * 2, dp[p_3] \ * 3, dp[p_5] \ * 5)$,然后分别比较 $dp[i]$ 与 $dp[p_2] \ * 2$、$dp[p_3] \ * 3$、$dp[p_5] \ * 5$ 是否相等,若是,则对应的指针加 $1$。
56+
57+
最后返回 $dp[n-1]$ 即可。
58+
59+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。
5260

5361
<!-- tabs:start -->
5462

5563
### **Python3**
5664

5765
<!-- 这里可写当前语言的特殊实现逻辑 -->
5866

67+
```python
68+
class Solution:
69+
def nthUglyNumber(self, n: int) -> int:
70+
h = [1]
71+
vis = {1}
72+
ans = 1
73+
for _ in range(n):
74+
ans = heappop(h)
75+
for v in [2, 3, 5]:
76+
nxt = ans * v
77+
if nxt not in vis:
78+
vis.add(nxt)
79+
heappush(h, nxt)
80+
return ans
81+
```
82+
5983
```python
6084
class Solution:
6185
def nthUglyNumber(self, n: int) -> int:
@@ -77,6 +101,29 @@ class Solution:
77101

78102
<!-- 这里可写当前语言的特殊实现逻辑 -->
79103

104+
```java
105+
class Solution {
106+
public int nthUglyNumber(int n) {
107+
Set<Long> vis = new HashSet<>();
108+
PriorityQueue<Long> q = new PriorityQueue<>();
109+
int[] f = new int[]{2, 3, 5};
110+
q.offer(1L);
111+
vis.add(1L);
112+
long ans = 0;
113+
while (n-- > 0) {
114+
ans = q.poll();
115+
for (int v : f) {
116+
long next = ans * v;
117+
if (vis.add(next)) {
118+
q.offer(next);
119+
}
120+
}
121+
}
122+
return (int) ans;
123+
}
124+
}
125+
```
126+
80127
```java
81128
class Solution {
82129
public int nthUglyNumber(int n) {
@@ -116,29 +163,31 @@ public:
116163
};
117164
```
118165
119-
### **JavaScript**
120-
121-
```js
122-
/**
123-
* @param {number} n
124-
* @return {number}
125-
*/
126-
var nthUglyNumber = function (n) {
127-
let dp = [1];
128-
let p2 = 0,
129-
p3 = 0,
130-
p5 = 0;
131-
for (let i = 1; i < n; ++i) {
132-
const next2 = dp[p2] * 2,
133-
next3 = dp[p3] * 3,
134-
next5 = dp[p5] * 5;
135-
dp[i] = Math.min(next2, Math.min(next3, next5));
136-
if (dp[i] == next2) ++p2;
137-
if (dp[i] == next3) ++p3;
138-
if (dp[i] == next5) ++p5;
139-
dp.push(dp[i]);
166+
```cpp
167+
class Solution {
168+
public:
169+
int nthUglyNumber(int n) {
170+
priority_queue<long, vector<long>, greater<long>> q;
171+
q.push(1l);
172+
unordered_set<long> vis{{1l}};
173+
long ans = 1;
174+
vector<int> f = {2, 3, 5};
175+
while (n--)
176+
{
177+
ans = q.top();
178+
q.pop();
179+
for (int& v : f)
180+
{
181+
long nxt = ans * v;
182+
if (!vis.count(nxt))
183+
{
184+
vis.insert(nxt);
185+
q.push(nxt);
186+
}
187+
}
188+
}
189+
return (int) ans;
140190
}
141-
return dp[n - 1];
142191
};
143192
```
144193

@@ -173,6 +222,69 @@ func min(a, b int) int {
173222
}
174223
```
175224

225+
```go
226+
func nthUglyNumber(n int) int {
227+
h := IntHeap([]int{1})
228+
heap.Init(&h)
229+
ans := 1
230+
vis := map[int]bool{1: true}
231+
for n > 0 {
232+
ans = heap.Pop(&h).(int)
233+
for _, v := range []int{2, 3, 5} {
234+
nxt := ans * v
235+
if !vis[nxt] {
236+
vis[nxt] = true
237+
heap.Push(&h, nxt)
238+
}
239+
}
240+
n--
241+
}
242+
return ans
243+
}
244+
245+
type IntHeap []int
246+
247+
func (h IntHeap) Len() int { return len(h) }
248+
func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] }
249+
func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
250+
func (h *IntHeap) Push(x interface{}) {
251+
*h = append(*h, x.(int))
252+
}
253+
func (h *IntHeap) Pop() interface{} {
254+
old := *h
255+
n := len(old)
256+
x := old[n-1]
257+
*h = old[0 : n-1]
258+
return x
259+
}
260+
```
261+
262+
### **JavaScript**
263+
264+
```js
265+
/**
266+
* @param {number} n
267+
* @return {number}
268+
*/
269+
var nthUglyNumber = function (n) {
270+
let dp = [1];
271+
let p2 = 0,
272+
p3 = 0,
273+
p5 = 0;
274+
for (let i = 1; i < n; ++i) {
275+
const next2 = dp[p2] * 2,
276+
next3 = dp[p3] * 3,
277+
next5 = dp[p5] * 5;
278+
dp[i] = Math.min(next2, Math.min(next3, next5));
279+
if (dp[i] == next2) ++p2;
280+
if (dp[i] == next3) ++p3;
281+
if (dp[i] == next5) ++p5;
282+
dp.push(dp[i]);
283+
}
284+
return dp[n - 1];
285+
};
286+
```
287+
176288
### **C#**
177289

178290
```cs

solution/0200-0299/0264.Ugly Number II/README_EN.md

Lines changed: 126 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,22 @@
3838

3939
### **Python3**
4040

41+
```python
42+
class Solution:
43+
def nthUglyNumber(self, n: int) -> int:
44+
h = [1]
45+
vis = {1}
46+
ans = 1
47+
for _ in range(n):
48+
ans = heappop(h)
49+
for v in [2, 3, 5]:
50+
nxt = ans * v
51+
if nxt not in vis:
52+
vis.add(nxt)
53+
heappush(h, nxt)
54+
return ans
55+
```
56+
4157
```python
4258
class Solution:
4359
def nthUglyNumber(self, n: int) -> int:
@@ -75,6 +91,29 @@ class Solution {
7591
}
7692
```
7793

94+
```java
95+
class Solution {
96+
public int nthUglyNumber(int n) {
97+
Set<Long> vis = new HashSet<>();
98+
PriorityQueue<Long> q = new PriorityQueue<>();
99+
int[] f = new int[]{2, 3, 5};
100+
q.offer(1L);
101+
vis.add(1L);
102+
long ans = 0;
103+
while (n-- > 0) {
104+
ans = q.poll();
105+
for (int v : f) {
106+
long next = ans * v;
107+
if (vis.add(next)) {
108+
q.offer(next);
109+
}
110+
}
111+
}
112+
return (int) ans;
113+
}
114+
}
115+
```
116+
78117
### **C++**
79118

80119
```cpp
@@ -96,29 +135,31 @@ public:
96135
};
97136
```
98137
99-
### **JavaScript**
100-
101-
```js
102-
/**
103-
* @param {number} n
104-
* @return {number}
105-
*/
106-
var nthUglyNumber = function (n) {
107-
let dp = [1];
108-
let p2 = 0,
109-
p3 = 0,
110-
p5 = 0;
111-
for (let i = 1; i < n; ++i) {
112-
const next2 = dp[p2] * 2,
113-
next3 = dp[p3] * 3,
114-
next5 = dp[p5] * 5;
115-
dp[i] = Math.min(next2, Math.min(next3, next5));
116-
if (dp[i] == next2) ++p2;
117-
if (dp[i] == next3) ++p3;
118-
if (dp[i] == next5) ++p5;
119-
dp.push(dp[i]);
138+
```cpp
139+
class Solution {
140+
public:
141+
int nthUglyNumber(int n) {
142+
priority_queue<long, vector<long>, greater<long>> q;
143+
q.push(1l);
144+
unordered_set<long> vis{{1l}};
145+
long ans = 1;
146+
vector<int> f = {2, 3, 5};
147+
while (n--)
148+
{
149+
ans = q.top();
150+
q.pop();
151+
for (int& v : f)
152+
{
153+
long nxt = ans * v;
154+
if (!vis.count(nxt))
155+
{
156+
vis.insert(nxt);
157+
q.push(nxt);
158+
}
159+
}
160+
}
161+
return (int) ans;
120162
}
121-
return dp[n - 1];
122163
};
123164
```
124165

@@ -153,6 +194,69 @@ func min(a, b int) int {
153194
}
154195
```
155196

197+
```go
198+
func nthUglyNumber(n int) int {
199+
h := IntHeap([]int{1})
200+
heap.Init(&h)
201+
ans := 1
202+
vis := map[int]bool{1: true}
203+
for n > 0 {
204+
ans = heap.Pop(&h).(int)
205+
for _, v := range []int{2, 3, 5} {
206+
nxt := ans * v
207+
if !vis[nxt] {
208+
vis[nxt] = true
209+
heap.Push(&h, nxt)
210+
}
211+
}
212+
n--
213+
}
214+
return ans
215+
}
216+
217+
type IntHeap []int
218+
219+
func (h IntHeap) Len() int { return len(h) }
220+
func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] }
221+
func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
222+
func (h *IntHeap) Push(x interface{}) {
223+
*h = append(*h, x.(int))
224+
}
225+
func (h *IntHeap) Pop() interface{} {
226+
old := *h
227+
n := len(old)
228+
x := old[n-1]
229+
*h = old[0 : n-1]
230+
return x
231+
}
232+
```
233+
234+
### **JavaScript**
235+
236+
```js
237+
/**
238+
* @param {number} n
239+
* @return {number}
240+
*/
241+
var nthUglyNumber = function (n) {
242+
let dp = [1];
243+
let p2 = 0,
244+
p3 = 0,
245+
p5 = 0;
246+
for (let i = 1; i < n; ++i) {
247+
const next2 = dp[p2] * 2,
248+
next3 = dp[p3] * 3,
249+
next5 = dp[p5] * 5;
250+
dp[i] = Math.min(next2, Math.min(next3, next5));
251+
if (dp[i] == next2) ++p2;
252+
if (dp[i] == next3) ++p3;
253+
if (dp[i] == next5) ++p5;
254+
dp.push(dp[i]);
255+
}
256+
return dp[n - 1];
257+
};
258+
```
259+
156260
### **C#**
157261

158262
```cs

0 commit comments

Comments
 (0)