Skip to content

Commit 72bc878

Browse files
author
hieu
committed
Solve Problem 166 - Fraction To Recurring Decimal
1 parent 8d4570c commit 72bc878

File tree

2 files changed

+104
-1
lines changed

2 files changed

+104
-1
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package twopointers.slowfast;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
public class Problem166_FractionToRecurringDecimal {
7+
8+
public String fractionToDecimal1(int numerator, int denominator) {
9+
if (denominator == 0) return "";
10+
long m = (long)numerator, n = (long)denominator;
11+
StringBuilder sb = new StringBuilder();
12+
13+
// handle sign
14+
if (m > 0 && n < 0) {
15+
sb.append('-');
16+
n = -n;
17+
}
18+
if (m < 0 && n > 0) {
19+
sb.append('-');
20+
m = -m;
21+
}
22+
23+
// handle integral part
24+
sb.append(m/n);
25+
m %= n;
26+
if (m == 0) return sb.toString();
27+
28+
// handle fractional part
29+
Map<Long, Integer> map = new HashMap<>();
30+
sb.append('.');
31+
map.put(m, sb.length());
32+
while (m != 0) {
33+
m *= 10;
34+
sb.append(m/n);
35+
m %= n;
36+
if (map.containsKey(m)) {
37+
int index = map.get(m);
38+
sb.insert(index, '(');
39+
sb.append(')');
40+
break;
41+
}
42+
else {
43+
map.put(m, sb.length());
44+
}
45+
}
46+
47+
return sb.toString();
48+
}
49+
50+
51+
public String fractionToDecimal(int numerator, int denominator) {
52+
StringBuilder sb = new StringBuilder();
53+
if ((numerator > 0 && denominator < 0) || (numerator < 0 && denominator > 0)) {
54+
sb.append("-");
55+
}
56+
long nLong = Math.abs((long) numerator);
57+
long dLong = Math.abs((long) denominator);
58+
sb.append(nLong / dLong);
59+
nLong %= dLong;
60+
if (nLong == 0) {
61+
return sb.toString();
62+
}
63+
sb.append('.');
64+
nLong *= 10;
65+
66+
// cycle detection
67+
long slow = nLong;
68+
long fast = nLong;
69+
while (fast != 0) {
70+
slow = next(slow, dLong);
71+
fast = next(next(fast, dLong), dLong);
72+
if (slow == fast) break;
73+
}
74+
// 2 cases: slow == fast or fast == 0
75+
slow = nLong;
76+
if (fast == 0) {
77+
while (slow != 0) {
78+
sb.append(slow / dLong);
79+
slow = next(slow, dLong);
80+
}
81+
return sb.toString();
82+
}
83+
// has cycle
84+
while (slow != fast) {
85+
sb.append(slow / dLong);
86+
slow = next(slow, dLong);
87+
fast = next(fast, dLong);
88+
}
89+
long cycleStart = slow;
90+
sb.append("(");
91+
do {
92+
sb.append(slow / dLong);
93+
slow = next(slow, dLong);
94+
} while (slow != cycleStart);
95+
sb.append(")");
96+
return sb.toString();
97+
}
98+
99+
private long next(long numerator, long denominator) {
100+
numerator %= denominator;
101+
return numerator * 10;
102+
}
103+
}

src/twopointers/Problem457_CircularArrayLoop.java renamed to src/twopointers/slowfast/Problem457_CircularArrayLoop.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package twopointers;
1+
package twopointers.slowfast;
22

33
public class Problem457_CircularArrayLoop {
44

0 commit comments

Comments
 (0)