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 54e5986

Browse files
Merge pull request SharingSource#354 from SharingSource/ac_oier
✨feat: Add 1447
2 parents 074031a + 853f5d0 commit 54e5986

File tree

2 files changed

+128
-0
lines changed

2 files changed

+128
-0
lines changed

‎Index/数学.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
| [1310. 子数组异或查询](https://leetcode-cn.com/problems/xor-queries-of-a-subarray/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/xor-queries-of-a-subarray/solution/gong-shui-san-xie-yi-ti-shuang-jie-shu-z-rcgu/) | 中等 | 🤩🤩🤩🤩 |
4848
| [1342. 将数字变成 0 的操作次数](https://leetcode-cn.com/problems/number-of-steps-to-reduce-a-number-to-zero/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/number-of-steps-to-reduce-a-number-to-zero/solution/gong-shui-san-xie-note-bie-pian-yi-ti-sh-85fb/) | 简单 | 🤩🤩🤩🤩 |
4949
| [1442. 形成两个异或相等数组的三元组数目](https://leetcode-cn.com/problems/count-triplets-that-can-form-two-arrays-of-equal-xor/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/count-triplets-that-can-form-two-arrays-of-equal-xor/solution/gong-shui-san-xie-xiang-jie-shi-yong-qia-7gzm/) | 中等 | 🤩🤩🤩 |
50+
| [1447. 最简分数](https://leetcode-cn.com/problems/simplified-fractions/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/simplified-fractions/solution/gong-shui-san-xie-jian-dan-shu-lun-yun-y-wma5/) | 中等 | 🤩🤩🤩🤩🤩 |
5051
| [1486. 数组异或操作](https://leetcode-cn.com/problems/xor-operation-in-an-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/xor-operation-in-an-array/solution/gong-shui-san-xie-yi-ti-shuang-jie-mo-ni-dggg/) | 简单 | 🤩🤩🤩 |
5152
| [1518. 换酒问题](https://leetcode-cn.com/problems/water-bottles/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/water-bottles/solution/gong-shui-san-xie-yi-ti-shuang-jie-ji-sh-7yyo/) | 简单 | 🤩🤩🤩🤩 |
5253
| [1588. 所有奇数长度子数组的和](https://leetcode-cn.com/problems/sum-of-all-odd-length-subarrays/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/sum-of-all-odd-length-subarrays/solution/gong-shui-san-xie-yi-ti-shuang-jie-qian-18jq3/) | 简单 | 🤩🤩🤩🤩 |
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[1447. 最简分数](https://leetcode-cn.com/problems/simplified-fractions/solution/gong-shui-san-xie-jian-dan-shu-lun-yun-y-wma5/)** ,难度为 **中等**
4+
5+
Tag : 「数学」、「最大公约数」
6+
7+
8+
9+
给你一个整数 `n` ,请你返回所有 0ドル$ 到 1ドル$ 之间(不包括 0ドル$ 和 1ドル$)满足分母小于等于 `n` 的 最简 分数 。分数可以以 **任意** 顺序返回。
10+
11+
示例 1:
12+
```
13+
输入:n = 2
14+
15+
输出:["1/2"]
16+
17+
解释:"1/2" 是唯一一个分母小于等于 2 的最简分数。
18+
```
19+
示例 2:
20+
```
21+
输入:n = 3
22+
23+
输出:["1/2","1/3","2/3"]
24+
```
25+
示例 3:
26+
```
27+
输入:n = 4
28+
29+
输出:["1/2","1/3","1/4","2/3","3/4"]
30+
31+
解释:"2/4" 不是最简分数,因为它可以化简为 "1/2" 。
32+
```
33+
示例 4:
34+
```
35+
输入:n = 1
36+
37+
输出:[]
38+
```
39+
40+
提示:
41+
* 1ドル <= n <= 100$
42+
43+
---
44+
45+
### 数论
46+
47+
数据范围为 100ドル$ 且数值大小在 $(0, 1)$ 之间,因此枚举「分子 + 分母」的 $O(n^2)$ 做法是可接受的。
48+
49+
于是问题转化为:**如何快速判断两个数组成的分数是否为最简(即判断两个数的最大公约数是否为 1ドル$)。**
50+
51+
快速求得 $a$ 和 $b$ 的最大公约数的主要方式有两种 :「更相减损法」和「欧几里得算法」,其中「欧几里得算法」的递归实现最为好写,复杂度为 $O(\log{(a + b)}),ドル在绝大多数的情况下适用,只有在需要实现高精度时,才会考虑使用「更相减损法」。
52+
53+
而 stein 算法则是没有必要掌握的。
54+
55+
代码:
56+
```Java
57+
class Solution {
58+
int gcd(int a, int b) { // 欧几里得算法
59+
return b == 0 ? a : gcd(b, a % b);
60+
}
61+
public List<String> simplifiedFractions(int n) {
62+
List<String> ans = new ArrayList<>();
63+
for (int i = 1; i < n; i++) {
64+
for (int j = i + 1; j <= n; j++) {
65+
if (gcd(i, j) == 1) ans.add(i + "/" + j);
66+
}
67+
}
68+
return ans;
69+
}
70+
}
71+
```
72+
-
73+
```Java
74+
class Solution {
75+
int gcd(int a, int b) { // 更相减损法
76+
while (true) {
77+
if (a > b) a -= b;
78+
else if (a < b) b -= a;
79+
else return a;
80+
}
81+
}
82+
public List<String> simplifiedFractions(int n) {
83+
List<String> ans = new ArrayList<>();
84+
for (int i = 1; i < n; i++) {
85+
for (int j = i + 1; j <= n; j++) {
86+
if (gcd(i, j) == 1) ans.add(i + "/" + j);
87+
}
88+
}
89+
return ans;
90+
}
91+
}
92+
```
93+
-
94+
```Java
95+
class Solution {
96+
int gcd(int a, int b) { // stein
97+
if (a == 0 || b == 0) return Math.max(a, b);
98+
if (a % 2 == 0 && b % 2 == 0) return 2 * gcd(a >> 1, b >> 1);
99+
else if (a % 2 == 0) return gcd(a >> 1, b);
100+
else if (b % 2 == 0) return gcd(a, b >> 1);
101+
else return gcd(Math.abs(a - b), Math.min(a, b));
102+
}
103+
public List<String> simplifiedFractions(int n) {
104+
List<String> ans = new ArrayList<>();
105+
for (int i = 1; i < n; i++) {
106+
for (int j = i + 1; j <= n; j++) {
107+
if (gcd(i, j) == 1) ans.add(i + "/" + j);
108+
}
109+
}
110+
return ans;
111+
}
112+
}
113+
```
114+
* 时间复杂度:枚举分子分母的复杂度为 $O(n^2)$;判断两数是否能凑成最简分数复杂度为 $O(\log{n})$。整体复杂度为 $O(n^2 * \log{n})$
115+
* 空间复杂度:忽略递归带来的额外空间开销,复杂度为 $O(1)$
116+
117+
---
118+
119+
### 最后
120+
121+
这是我们「刷穿 LeetCode」系列文章的第 `No.1447` 篇,系列开始于 2021年01月01日,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
122+
123+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
124+
125+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
126+
127+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

0 commit comments

Comments
(0)

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