Map记录已遍历过的值
思路
- 当分母相同时,分子从小到大一次递增;随着分母依次增大,肯定会出现值相同的分数,举个例子。
- 如4/6并不是最简分数,且4/6=2/3,而2/3肯定比4/6先 构成的。
- 所以用HashMap记录已经遍历过的最简分数,<k,v> <最简分数,1>
- 当构成新的分数时,新分数的值是否在map中存在。若存在,则忽略;否则为新的最简分数,同时map记录新的最简分数
代码
/**
*40ms
*/
public List<String> simplifiedFractions(int n) {
List<String> list=new ArrayList<>();
Map<Double,Integer> map=new HashMap<>();
if(n==1) return list;
for(int i=2;i<=n;i++){
for(int j=1;j<i;j++){
if(j!=1&&map.containsKey((j/(i*1.0)))){
continue;
}
map.put(j/(i*1.0), 1);
list.add(j+"/"+i);
}
}
return list;
}
求最大公约数(辗转相除法)
思路
- 求出分子分母的最大公约数,分子为1可以跳过计算
- 如果最大公约数为1,则满足要求
- 分母为1 无法构成最简分数
代码
/**
* 29ms
* 辗转相除法
*/
public List<String> simplifiedFractions2(int n){
List<String> list=new ArrayList<>();
if(n==1){
return list;
}
for(int i=2;i<=n;i++){
for(int j=1;j<i;j++){
if(j==1||gcd(i,j )==1){
list.add(j+"/"+i);
}
}
}
return list;
}
//辗转相除计算最大公约数
public int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}