Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit a909538

Browse files
authored
feat: add solutions to lc problem: No.1201 (#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)

AltStyle によって変換されたページ (->オリジナル) /