- 问题描述
给你一个整数
n
,请你返回所有 0 到 1 之间(不包括 0 和 1)满足分母小于等于n
的 最简 分数 。分数可以以 任意 顺序返回。
- 示例
输入:n = 2 输出:["1/2"] 解释:"1/2" 是唯一一个分母小于等于 2 的最简分数。 输入:n = 3 输出:["1/2","1/3","2/3"] 输入:n = 4 输出:["1/2","1/3","1/4","2/3","3/4"] 解释:"2/4" 不是最简分数,因为它可以化简为 "1/2" 。 输入:n = 1 输出:[]
- 提示:
1 <= n <= 100
- 解读
一、结果集设为 f(n) ,则有 f(n) = f(n -1) + 1/n + 2/n + ... + (n -1)/n。 因为用递归的方法,为了减少多case重复计算,我们保存每个 f(n)的结果 。
二、注意到有重复的情况 ,比如 1/ 2 跟 2/4 在求 f(4)的时候, 1/2 会有重复计算 ,所以用 set 结构,来保证结果的唯一性。
三、最简分数,相当于,分子分母互质,因为就要有一个求公约数的方法。
- 代码
class Solution {
Map<Integer, Set<String>> map = new HashMap<>();
public int getGcd(int m, int n) {
if (n % m == 0) {
return m;
}
return getGcd(n % m, m);
}
public String getFraction(int m, int n) {
int gcd = getGcd(m, n);
m = m / gcd;
n = n / gcd;
StringBuilder sb = new StringBuilder();
sb.append(m).append("/").append(n);
return sb.toString();
}
public Set<String> getGimplifiedFractions(int n) {
if (map.containsKey(n)) {
return map.get(n);
}
if (n == 1) {
map.put(1, new HashSet<>());
} else {
Set<String> rList = new HashSet<>(simplifiedFractions(n - 1));
for (int i = 1; i < n; i++) {
rList.add(getFraction(i, n));
}
map.put(n, rList);
}
return map.get(n);
}
public List<String> simplifiedFractions(int n){
return new ArrayList<>(getGimplifiedFractions(n));
}
}