Skip to content

Commit 2f126aa

Browse files
committed
feat: add solutions to lcci problem: No.17.09
No.17.09.Get Kth Magic Number
1 parent 5881e6a commit 2f126aa

File tree

9 files changed

+489
-13
lines changed

9 files changed

+489
-13
lines changed

lcci/17.09.Get Kth Magic Number/README.md

+203
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,225 @@
1717

1818
<!-- 这里可写通用的实现逻辑 -->
1919

20+
**方法一:优先队列(小根堆)**
21+
22+
用一个小根堆维护当前最小的数,每次取出最小的数,然后乘以 $3$, $5$, $7$,分别加入堆中,直到取出第 $k$ 个数。
23+
24+
时间复杂度 $O(k\times \log k)$,空间复杂度 $O(k)$。
25+
26+
**方法二:动态规划**
27+
28+
定义数组 `dp`,其中 `dp[i]` 表示第 $i$ 个数,答案即为 `dp[k]`
29+
30+
定义三个指针 `p3`, `p5`, `p7`,表示下一个数是当前指针指向的数乘以对应的质因数,初始值都为 $1$。
31+
32+
当 $2\le i \le k$ 时,令 $dp[i] = \min(dp[p_3\times 3], dp[p_5]\times 5, dp[p_7]\times 7)$,然后分别比较 $dp[i]$ 和 $dp[p_3]\times 3, dp[p_5]\times 5, dp[p_7]\times 7$,如果相等,则将对应的指针加 $1$。
33+
34+
时间复杂度 $O(k)$,空间复杂度 $O(k)$。
35+
2036
<!-- tabs:start -->
2137

2238
### **Python3**
2339

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

2642
```python
43+
class Solution:
44+
def getKthMagicNumber(self, k: int) -> int:
45+
h = [1]
46+
vis = {1}
47+
for _ in range(k - 1):
48+
cur = heappop(h)
49+
for f in (3, 5, 7):
50+
if (nxt := cur * f) not in vis:
51+
vis.add(nxt)
52+
heappush(h, nxt)
53+
return h[0]
54+
```
2755

56+
```python
57+
class Solution:
58+
def getKthMagicNumber(self, k: int) -> int:
59+
dp = [1] * (k + 1)
60+
p3 = p5 = p7 = 1
61+
for i in range(2, k + 1):
62+
a, b, c = dp[p3] * 3, dp[p5] * 5, dp[p7] * 7
63+
v = min(a, b, c)
64+
dp[i] = v
65+
if v == a:
66+
p3 += 1
67+
if v == b:
68+
p5 += 1
69+
if v == c:
70+
p7 += 1
71+
return dp[k]
2872
```
2973

3074
### **Java**
3175

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

3478
```java
79+
class Solution {
80+
private static final int[] FACTORS = new int[] {3, 5, 7};
81+
82+
public int getKthMagicNumber(int k) {
83+
PriorityQueue<Long> q = new PriorityQueue<>();
84+
Set<Long> vis = new HashSet<>();
85+
q.offer(1L);
86+
vis.add(1L);
87+
while (--k > 0) {
88+
long cur = q.poll();
89+
for (int f : FACTORS) {
90+
long nxt = cur * f;
91+
if (!vis.contains(nxt)) {
92+
q.offer(nxt);
93+
vis.add(nxt);
94+
}
95+
}
96+
}
97+
long ans = q.poll();
98+
return (int) ans;
99+
}
100+
}
101+
```
102+
103+
```java
104+
class Solution {
105+
public int getKthMagicNumber(int k) {
106+
int[] dp = new int[k + 1];
107+
Arrays.fill(dp, 1);
108+
int p3 = 1, p5 = 1, p7 = 1;
109+
for (int i = 2; i <= k; ++i) {
110+
int a = dp[p3] * 3, b = dp[p5] * 5, c = dp[p7] * 7;
111+
int v = Math.min(Math.min(a, b), c);
112+
dp[i] = v;
113+
if (v == a) {
114+
++p3;
115+
}
116+
if (v == b) {
117+
++p5;
118+
}
119+
if (v == c) {
120+
++p7;
121+
}
122+
}
123+
return dp[k];
124+
}
125+
}
126+
```
127+
128+
### **C++**
129+
130+
```cpp
131+
class Solution {
132+
public:
133+
const vector<int> factors = {3, 5, 7};
134+
135+
int getKthMagicNumber(int k) {
136+
priority_queue<long, vector<long>, greater<long>> q;
137+
unordered_set<long> vis;
138+
q.push(1l);
139+
vis.insert(1l);
140+
for (int i = 0; i < k - 1; ++i) {
141+
long cur = q.top();
142+
q.pop();
143+
for (int f : factors) {
144+
long nxt = cur * f;
145+
if (!vis.count(nxt)) {
146+
vis.insert(nxt);
147+
q.push(nxt);
148+
}
149+
}
150+
}
151+
return (int) q.top();
152+
}
153+
};
154+
```
155+
156+
```cpp
157+
class Solution {
158+
public:
159+
int getKthMagicNumber(int k) {
160+
vector<int> dp(k + 1, 1);
161+
int p3 = 1, p5 = 1, p7 = 1;
162+
for (int i = 2; i <= k; ++i) {
163+
int a = dp[p3] * 3, b = dp[p5] * 5, c = dp[p7] * 7;
164+
int v = min(min(a, b), c);
165+
dp[i] = v;
166+
if (v == a) {
167+
++p3;
168+
}
169+
if (v == b) {
170+
++p5;
171+
}
172+
if (v == c) {
173+
++p7;
174+
}
175+
}
176+
return dp[k];
177+
}
178+
};
179+
```
180+
181+
### **Go**
182+
183+
```go
184+
func getKthMagicNumber(k int) int {
185+
q := hp{[]int{1}}
186+
vis := map[int]bool{1: true}
187+
for i := 0; i < k-1; i++ {
188+
cur := heap.Pop(&q).(int)
189+
for _, f := range []int{3, 5, 7} {
190+
nxt := cur * f
191+
if !vis[nxt] {
192+
vis[nxt] = true
193+
heap.Push(&q, nxt)
194+
}
195+
}
196+
}
197+
return q.IntSlice[0]
198+
}
199+
200+
type hp struct{ sort.IntSlice }
201+
202+
func (h *hp) Push(v interface{}) { h.IntSlice = append(h.IntSlice, v.(int)) }
203+
func (h *hp) Pop() interface{} {
204+
a := h.IntSlice
205+
v := a[len(a)-1]
206+
h.IntSlice = a[:len(a)-1]
207+
return v
208+
}
209+
```
35210

211+
```go
212+
func getKthMagicNumber(k int) int {
213+
dp := make([]int, k+1)
214+
dp[1] = 1
215+
p3, p5, p7 := 1, 1, 1
216+
for i := 2; i <= k; i++ {
217+
a, b, c := dp[p3]*3, dp[p5]*5, dp[p7]*7
218+
v := min(min(a, b), c)
219+
dp[i] = v
220+
if v == a {
221+
p3++
222+
}
223+
if v == b {
224+
p5++
225+
}
226+
if v == c {
227+
p7++
228+
}
229+
}
230+
return dp[k]
231+
}
232+
233+
func min(a, b int) int {
234+
if a < b {
235+
return a
236+
}
237+
return b
238+
}
36239
```
37240

38241
### **...**

0 commit comments

Comments
 (0)