Skip to content

Commit a909538

Browse files
authored
feat: add solutions to lc problem: No.1201 (doocs#856)
No.1201.Ugly Number III
1 parent 57010f9 commit a909538

File tree

5 files changed

+263
-7
lines changed

5 files changed

+263
-7
lines changed

solution/1200-1299/1201.Ugly Number III/README.md

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,22 +56,117 @@
5656

5757
<!-- 这里可写通用的实现逻辑 -->
5858

59+
**方法一:二分搜索**
60+
61+
根据题目提示结果在 [1, 2 * 10<sup>9</sup>] 的闭区间上,所以定义二分搜索的左边界 left=1,右边界 right=2e9。此时我们只需要在 [left,right] 的闭区间内找到一个最小的数 num,使其满足 [1,num] 内的丑数总数等于 n,则 num 就是第 n 个丑数。计算在 [1,num] 的范围内丑数的数目,即可以被 a、b 或 c 任意一个数整除的数的总数,其方法如下:
62+
63+
`f(num, a, b, c) = num/a + num/b + num/c - a⋂b - a⋂c - b⋂c + a⋂b⋂c`
64+
65+
- num/a 表示在 [1,num] 内可以整除 a 的数目,num/b 表示在 [1,num] 内可以整除 b 的数目,num/c 表示在 [1,num] 内可以整除 c 的数目。
66+
- a⋂b 表示在 [1,num] 内可以同时整除 a 和 b 的数目,a⋂c 表示在 [1,num] 内可以同时整除 a 和 c 的数,b⋂c 表示在 [1,num] 内可以同时整除 b 和 c 的数。
67+
- a⋂b⋂c 表示在 [1,num] 内可以同时整除 a、b 和 c 的数。
68+
- a⋂b = num/least_common_multiple(a, b),其他情况依次类推。
69+
5970
<!-- tabs:start -->
6071

6172
### **Python3**
6273

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

6576
```python
66-
77+
class Solution:
78+
def f(self, num: int, a: int, b: int, c: int) -> int:
79+
return num // a + num // b + num // c - num // math.lcm(a, b) - num // math.lcm(a, c) - num // math.lcm(b, c) \
80+
+ num // math.lcm(a, b, c)
81+
82+
def nthUglyNumber(self, n: int, a: int, b: int, c: int) -> int:
83+
left, right = 1, int(2e9)
84+
while left <= right:
85+
mid = left + (right - left) // 2
86+
if self.f(mid, a, b, c) < n:
87+
left = mid + 1
88+
else:
89+
right = mid - 1
90+
return left
6791
```
6892

69-
### **Java**
93+
### **Go**
7094

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

73-
```java
97+
```go
98+
func nthUglyNumber(n int, a int, b int, c int) int {
99+
left, right := 1, int(2e9)
100+
for left <= right {
101+
mid := left + (right-left)/2
102+
if f(mid, a, b, c) < n {
103+
left = mid + 1
104+
} else {
105+
right = mid - 1
106+
}
107+
}
108+
return left
109+
}
110+
111+
func f(num int, a int, b int, c int) int {
112+
return num/a + num/b + num/c - num/lcm(a, b) - num/lcm(a, c) - num/lcm(b, c) + num/lcm(lcm(a, b), c)
113+
}
114+
115+
// Least common multiple
116+
func lcm(a, b int) int {
117+
// Greatest common divisor
118+
gcd := func(x, y int) int {
119+
for y != 0 {
120+
if x < y {
121+
x, y = y, x
122+
}
123+
x, y = y, x%y
124+
}
125+
return x
126+
}
127+
return a * b / gcd(a, b)
128+
}
129+
```
130+
131+
### **C++**
132+
133+
<!-- 这里可写当前语言的特殊实现逻辑 -->
74134

135+
```cpp
136+
class Solution {
137+
public:
138+
long gcd(long x, long y) {
139+
while (y != 0) {
140+
if (x < y)
141+
swap(x, y);
142+
long tmp = x % y;
143+
x = y;
144+
y = tmp;
145+
}
146+
return x;
147+
}
148+
149+
long lcm(long x, long y) { return x * y / gcd(x, y); }
150+
151+
long f(int num, int a, int b, int c) {
152+
long sumabc = long(num / a) + num / b + num / c;
153+
long intersections = long(num / lcm(a, b)) + num / lcm(a, c) + num / lcm(b, c) - num / lcm(lcm(a, b), c);
154+
return sumabc - intersections;
155+
}
156+
157+
int nthUglyNumber(int n, int a, int b, int c) {
158+
int left = 1, right = int(2e9);
159+
while (left <= right) {
160+
int mid = left + (right - left) / 2;
161+
if (f(mid, a, b, c) < n) {
162+
left = mid + 1;
163+
} else {
164+
right = mid - 1;
165+
}
166+
}
167+
return left;
168+
}
169+
};
75170
```
76171
77172
### **...**

solution/1200-1299/1201.Ugly Number III/README_EN.md

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,95 @@
4949
### **Python3**
5050

5151
```python
52-
52+
class Solution:
53+
def f(self, num: int, a: int, b: int, c: int) -> int:
54+
return num // a + num // b + num // c - num // math.lcm(a, b) - num // math.lcm(a, c) - num // math.lcm(b, c) \
55+
+ num // math.lcm(a, b, c)
56+
57+
def nthUglyNumber(self, n: int, a: int, b: int, c: int) -> int:
58+
left, right = 1, int(2e9)
59+
while left <= right:
60+
mid = left + (right - left) // 2
61+
if self.f(mid, a, b, c) < n:
62+
left = mid + 1
63+
else:
64+
right = mid - 1
65+
return left
5366
```
5467

55-
### **Java**
56-
57-
```java
68+
### **Go**
69+
70+
```go
71+
func nthUglyNumber(n int, a int, b int, c int) int {
72+
left, right := 1, int(2e9)
73+
for left <= right {
74+
mid := left + (right-left)/2
75+
if f(mid, a, b, c) < n {
76+
left = mid + 1
77+
} else {
78+
right = mid - 1
79+
}
80+
}
81+
return left
82+
}
83+
84+
func f(num int, a int, b int, c int) int {
85+
return num/a + num/b + num/c - num/lcm(a, b) - num/lcm(a, c) - num/lcm(b, c) + num/lcm(lcm(a, b), c)
86+
}
87+
88+
// Least common multiple
89+
func lcm(a, b int) int {
90+
// Greatest common divisor
91+
gcd := func(x, y int) int {
92+
for y != 0 {
93+
if x < y {
94+
x, y = y, x
95+
}
96+
x, y = y, x%y
97+
}
98+
return x
99+
}
100+
return a * b / gcd(a, b)
101+
}
102+
```
58103

104+
### **C++**
105+
106+
```cpp
107+
class Solution {
108+
public:
109+
long gcd(long x, long y) {
110+
while (y != 0) {
111+
if (x < y)
112+
swap(x, y);
113+
long tmp = x % y;
114+
x = y;
115+
y = tmp;
116+
}
117+
return x;
118+
}
119+
120+
long lcm(long x, long y) { return x * y / gcd(x, y); }
121+
122+
long f(int num, int a, int b, int c) {
123+
long sumabc = long(num / a) + num / b + num / c;
124+
long intersections = long(num / lcm(a, b)) + num / lcm(a, c) + num / lcm(b, c) - num / lcm(lcm(a, b), c);
125+
return sumabc - intersections;
126+
}
127+
128+
int nthUglyNumber(int n, int a, int b, int c) {
129+
int left = 1, right = int(2e9);
130+
while (left <= right) {
131+
int mid = left + (right - left) / 2;
132+
if (f(mid, a, b, c) < n) {
133+
left = mid + 1;
134+
} else {
135+
right = mid - 1;
136+
}
137+
}
138+
return left;
139+
}
140+
};
59141
```
60142
61143
### **...**
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
class Solution {
2+
public:
3+
long gcd(long x, long y) {
4+
while (y != 0) {
5+
if (x < y)
6+
swap(x, y);
7+
long tmp = x % y;
8+
x = y;
9+
y = tmp;
10+
}
11+
return x;
12+
}
13+
14+
long lcm(long x, long y) { return x * y / gcd(x, y); }
15+
16+
long f(int num, int a, int b, int c) {
17+
long sumabc = long(num / a) + num / b + num / c;
18+
long intersections = long(num / lcm(a, b)) + num / lcm(a, c) + num / lcm(b, c) - num / lcm(lcm(a, b), c);
19+
return sumabc - intersections;
20+
}
21+
22+
int nthUglyNumber(int n, int a, int b, int c) {
23+
int left = 1, right = int(2e9);
24+
while (left <= right) {
25+
int mid = left + (right - left) / 2;
26+
if (f(mid, a, b, c) < n) {
27+
left = mid + 1;
28+
} else {
29+
right = mid - 1;
30+
}
31+
}
32+
return left;
33+
}
34+
};
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
func nthUglyNumber(n int, a int, b int, c int) int {
2+
left, right := 1, int(2e9)
3+
for left <= right {
4+
mid := left + (right-left)/2
5+
if f(mid, a, b, c) < n {
6+
left = mid + 1
7+
} else {
8+
right = mid - 1
9+
}
10+
}
11+
return left
12+
}
13+
14+
func f(num int, a int, b int, c int) int {
15+
return num/a + num/b + num/c - num/lcm(a, b) - num/lcm(a, c) - num/lcm(b, c) + num/lcm(lcm(a, b), c)
16+
}
17+
18+
// Least common multiple
19+
func lcm(a, b int) int {
20+
// Greatest common divisor
21+
gcd := func(x, y int) int {
22+
for y != 0 {
23+
if x < y {
24+
x, y = y, x
25+
}
26+
x, y = y, x%y
27+
}
28+
return x
29+
}
30+
return a * b / gcd(a, b)
31+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class Solution:
2+
def f(self, num: int, a: int, b: int, c: int) -> int:
3+
return num // a + num // b + num // c - num // math.lcm(a, b) - num // math.lcm(a, c) - num // math.lcm(b, c) \
4+
+ num // math.lcm(a, b, c)
5+
6+
def nthUglyNumber(self, n: int, a: int, b: int, c: int) -> int:
7+
left, right = 1, int(2e9)
8+
while left <= right:
9+
mid = left + (right - left) // 2
10+
if self.f(mid, a, b, c) < n:
11+
left = mid + 1
12+
else:
13+
right = mid - 1
14+
return left

0 commit comments

Comments
 (0)