先不管循环小数,写一个除法递归,直到除尽
考虑循环,那么从第二次循环开始,递归方法中被除数必定是已经出现过了,我用了一个Map集合保存每一个出现过的 被除数 ,当重复出现时停止递归返回 一个空字符串,并用一个变量保存是在哪一个 被除数 处停止的。这样的话,当递归返回至第一次循环(第二次循环的第一个数就停止了)时,就能通过该变量直到是在这里开始循环的,然后加上() 返回给上一层。
递归的方法的耗时会比while循环慢很多(如果可以写成while 循环的话)
所以我尝试着换了一种写法
此处有个疑问,题解的写法能达到 1ms,但我需要 5ms,朝着题解的写法修改后仍然只能 5ms,不知道问什么
自己的
递归(13ms)
class Solution {
Map<Long,Integer> m = new HashMap<>();
Long rec = 0L;
public String fractionToDecimal(int numerator, int denominator) {
if(numerator == 0)
return "0";
long numerator0 = Math.abs(numerator * 1L);
long denominator0 = Math.abs(denominator * 1L);
StringBuilder s = new StringBuilder();
if((numerator < 0 ^ denominator < 0))
s.append("-");
if(numerator0 % denominator0 == 0)
s.append(numerator0 / denominator0 + "");
else
s.append(numerator0 / denominator0 + ".");
s.append(tool((numerator0 % denominator0) * 10,denominator0));
return s.toString();
}
String tool(long numerator, long denominator){
if(numerator == 0)
return "";
if(m.containsKey(numerator)){
rec = numerator;
return "";
}
m.put(numerator,0);
StringBuilder t = new StringBuilder();
t.append(numerator / denominator + tool((numerator % denominator) * 10,denominator));
if(rec == numerator)
return "(" + t.toString() + ")";
return t.toString();
}
}
while循环(5ms)
class Solution {
public String fractionToDecimal(int numerator, int denominator) {
if(numerator == 0)
return "0";
long numerator0 = Math.abs(numerator * 1L);
long denominator0 = Math.abs(denominator * 1L);
StringBuilder s = new StringBuilder();
if((numerator < 0 ^ denominator < 0))
s.append("-");
if(numerator0 % denominator0 == 0)
s.append(numerator0 / denominator0);
else
s.append(numerator0 / denominator0 + ".");
numerator0 =(numerator0 % denominator0) * 10;
StringBuilder t = new StringBuilder();
Map<Long,Integer> m = new HashMap<>();
int rec = 0;
while(numerator0 != 0){
if(m.containsKey(numerator0)){
t.insert(m.get(numerator0),"(");
t.append(")");
break;
}
t.append(numerator0 / denominator0);
m.put(numerator0,rec++);
numerator0 = (numerator0 % denominator0) * 10;
}
s.append(t);
return s.toString();
}
}
题解(1ms)
class Solution {
public String fractionToDecimal(int numerator, int denominator) {
long numeratorlong=(long)numerator;
long denominatorlong=(long)denominator;
StringBuffer sb=new StringBuffer();
if(numeratorlong%denominatorlong==0){
return String.valueOf(numeratorlong/denominatorlong);
}
if(numeratorlong<0 ^ denominatorlong<0){
sb.append('-');
}
long n=Math.abs(numeratorlong); long d=Math.abs(denominatorlong);
long integerpart=n/d;
sb.append(integerpart);
sb.append('.');
StringBuffer fractionpart=new StringBuffer();
long remain=n%d;
int index=0;
Map<Long,Integer> remainindexmap=new HashMap<>();
while(remain!=0 && !remainindexmap.containsKey(remain)){
remainindexmap.put(remain,index);
remain*=10;
fractionpart.append(remain/d);
remain%=d;
index++;
}
if(remain!=0){
int insertindex=remainindexmap.get(remain);
fractionpart.insert(insertindex,'(');
fractionpart.append(')');
}
sb.append(fractionpart.toString());
return sb.toString();
}
}