您的位置:首页 > 其它

leetcode(166) Fraction to Recurring Decimal

2016-03-10 15:30 239 查看
原题链接:https://leetcode.com/problems/fraction-to-recurring-decimal/

这道题就是做除法,然后如果有无限循环的部分用括号表示

比如1/3=0.3333...用0.(3)来表示,1234/9999=0.123412341234....用0.(1234)来表示

循环判断用一个map来查看前面的一个数(或一串数)是否与后面的一个数(或一串数)做除法后的余数是否相同

具体思路如下图(这张图是从某篇其它博客上发现的,后来找不到原博了,如果有哪位读者发现,请告诉我),就是小学生的除法问题:



首先先说一种错误思路,这种只考虑了1/3,1/6这种答案中只有一个数字循环的条件。实际上一串循环的数也是有的比如上面的例子1234/9999

错误解法(逻辑有问题且超时):

/**
* Time Limit Exceeded 无法处理1234/9999这种
*
* @param numerator
* @param denominator
* @return
*/
public static String fractionToDecimal(int numerator, int denominator) {
if (denominator == 0) {
return null;
}
if (numerator == 0) {
return 0 + "";
}
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
String result = "";
if (numerator < 0 ^ denominator < 0)
result += '-';
numerator = Math.abs(numerator);
denominator = Math.abs(denominator);
int temp = 0;
if ((temp = numerator / denominator) != 0) {
result += temp + "";
if ((temp = numerator % denominator) == 0) {
return result;
} else {
result += ".";
}
} else {
temp = numerator % denominator;
result += "0.";
}
while ((temp * 10 % denominator) != 0) {
int mod = temp * 10 % denominator;
int divide = temp * 10 / denominator;
if (map.containsKey(mod)) {
result = result.substring(0, result.length() - 1);
result += "(" + divide + ")";
return result;
}
result += divide + "";
map.clear();
map.put(mod, mod);
temp = mod;
}
result += (temp * 10 / denominator) + "";
return result;
}见while循环里包含map的if中的处理。只是与上一个数进行比较,下面有一个map.clear然后再put,这样造成了只存取一位数,显然错误。
正确的解法:

public static String fractionToDecimal(int numerator, int denominator) {
long n = numerator, d = denominator;
if (n == 0)
return "0";

StringBuffer a = new StringBuffer();
if ((n < 0) ^ (d < 0))
a.append("-");

n = Math.abs(n);
d = Math.abs(d);

long in = n / d;
a.append(String.valueOf(in)); // StringBuffer里面没有String的 a = a +

if (n % d == 0) {
return a.toString();
} else {
a.append(".");
}
// 以上是小数点以前的

HashMap<Long, Integer> map = new HashMap<Long, Integer>();
// 用hashmap查找循环的地方比较方便
// System.out.println(map.get(0)); //打印可看出 integer位置上未初始化时存的是null
long i;
for (i = n % d; i != 0; i = i % d) { // 注意step
if (map.get(i) != null) {
break;
}
map.put(i, a.length()); // 将i的值当做key a的位置当做value
i *= 10;
a.append(i / d);
}
if (i == 0)
return a.toString();
a.insert(map.get(i), "("); // 直接在循环的地方加入(
a.append(")"); // 出现循环就立即跳出了循环,也就是说从i的位置到最后,都是循环体,所以只需在最后面加上)
return a.toString();
}注意循环条件,for(i=n%d;i!=0;i=i%d),i=n%d代表余数(初始值),每次走i%d步,i在循环里有一步是i*10,当余数相同的情况下,说明后面该循环了。然后跳出循环,此时map中记录的位置即是要放左括号"("的位置,结尾是放右括号")"的位置。
以上就是此题的题解。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode