Overflow in intermediate arithmetic
Wrong move: Temporary multiplications exceed integer bounds.
Usually fails on: Large inputs wrap around unexpectedly.
Fix: Use wider types, modular arithmetic, or rearranged operations.
Move from brute-force thinking to an efficient approach using math strategy.
Given a string expression representing an expression of fraction addition and subtraction, return the calculation result in string format.
The final result should be an irreducible fraction. If your final result is an integer, change it to the format of a fraction that has a denominator 1. So in this case, 2 should be converted to 2/1.
Example 1:
Input: expression = "-1/2+1/2" Output: "0/1"
Example 2:
Input: expression = "-1/2+1/2+1/3" Output: "1/3"
Example 3:
Input: expression = "1/3-1/2" Output: "-1/6"
Constraints:
'0' to '9', '/', '+' and '-'. So does the output.±numerator/denominator. If the first input fraction or the output is positive, then '+' will be omitted.[1, 10]. If the denominator is 1, it means this fraction is actually an integer in a fraction format defined above.[1, 10].Problem summary: Given a string expression representing an expression of fraction addition and subtraction, return the calculation result in string format. The final result should be an irreducible fraction. If your final result is an integer, change it to the format of a fraction that has a denominator 1. So in this case, 2 should be converted to 2/1.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Math
"-1/2+1/2"
"-1/2+1/2+1/3"
"1/3-1/2"
solve-the-equation)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #592: Fraction Addition and Subtraction
class Solution {
public String fractionAddition(String expression) {
int x = 0, y = 6 * 7 * 8 * 9 * 10;
if (Character.isDigit(expression.charAt(0))) {
expression = "+" + expression;
}
int i = 0, n = expression.length();
while (i < n) {
int sign = expression.charAt(i) == '-' ? -1 : 1;
++i;
int j = i;
while (j < n && expression.charAt(j) != '+' && expression.charAt(j) != '-') {
++j;
}
String s = expression.substring(i, j);
String[] t = s.split("/");
int a = Integer.parseInt(t[0]), b = Integer.parseInt(t[1]);
x += sign * a * y / b;
i = j;
}
int z = gcd(Math.abs(x), y);
x /= z;
y /= z;
return x + "/" + y;
}
private int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
}
// Accepted solution for LeetCode #592: Fraction Addition and Subtraction
func fractionAddition(expression string) string {
x, y := 0, 6*7*8*9*10
if unicode.IsDigit(rune(expression[0])) {
expression = "+" + expression
}
i, n := 0, len(expression)
for i < n {
sign := 1
if expression[i] == '-' {
sign = -1
}
i++
j := i
for j < n && expression[j] != '+' && expression[j] != '-' {
j++
}
s := expression[i:j]
t := strings.Split(s, "/")
a, _ := strconv.Atoi(t[0])
b, _ := strconv.Atoi(t[1])
x += sign * a * y / b
i = j
}
z := gcd(abs(x), y)
x /= z
y /= z
return fmt.Sprintf("%d/%d", x, y)
}
func abs(x int) int {
if x < 0 {
return -x
}
return x
}
func gcd(a, b int) int {
if b == 0 {
return a
}
return gcd(b, a%b)
}
# Accepted solution for LeetCode #592: Fraction Addition and Subtraction
class Solution:
def fractionAddition(self, expression: str) -> str:
x, y = 0, 6 * 7 * 8 * 9 * 10
if expression[0].isdigit():
expression = '+' + expression
i, n = 0, len(expression)
while i < n:
sign = -1 if expression[i] == '-' else 1
i += 1
j = i
while j < n and expression[j] not in '+-':
j += 1
s = expression[i:j]
a, b = s.split('/')
x += sign * int(a) * y // int(b)
i = j
z = gcd(x, y)
x //= z
y //= z
return f'{x}/{y}'
// Accepted solution for LeetCode #592: Fraction Addition and Subtraction
struct Solution;
use std::fmt::{Display, Formatter, Result};
enum Tok {
Op(char),
Num(i32),
}
struct Fraction {
sign: i32,
numerator: i32,
denominator: i32,
}
impl Fraction {
fn new(sign: i32, numerator: i32, denominator: i32) -> Self {
Fraction {
sign,
numerator,
denominator,
}
}
fn add(self, other: Self) -> Self {
let mut numerator = self.sign * self.numerator * other.denominator
+ other.sign * other.numerator * self.denominator;
let denominator = self.denominator * other.denominator;
let mut sign = 1;
if numerator < 0 {
sign *= -1;
numerator *= -1;
}
Fraction {
sign,
numerator,
denominator,
}
}
fn reduce(self) -> Self {
let sign = self.sign;
let mut denominator = self.denominator;
let mut numerator = self.numerator;
let gcd = gcd(denominator, numerator);
denominator /= gcd;
numerator /= gcd;
Fraction {
sign,
numerator,
denominator,
}
}
}
impl Display for Fraction {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
if self.sign > 0 {
write!(f, "{}/{}", self.numerator, self.denominator)
} else {
write!(f, "-{}/{}", self.numerator, self.denominator)
}
}
}
fn gcd(mut m: i32, mut n: i32) -> i32 {
while m != 0 {
let temp = m;
m = n % temp;
n = temp;
}
n.abs()
}
impl Solution {
fn fraction_addition(expression: String) -> String {
let mut toks: Vec<Tok> = vec![];
let mut c_it = expression.chars().peekable();
while let Some(c) = c_it.next() {
match c {
'-' | '+' | '/' => {
toks.push(Tok::Op(c));
}
_ => {
let mut val = (c as u8 - b'0') as i32;
while let Some(p) = c_it.peek() {
if p.is_digit(10) {
val *= 10;
val += (c_it.next().unwrap() as u8 - b'0') as i32;
} else {
break;
}
}
toks.push(Tok::Num(val));
}
}
}
let mut t_it = toks.into_iter().peekable();
let mut fractions: Vec<Fraction> = vec![];
while t_it.peek().is_some() {
let mut sign = 1;
let numerator;
let denominator;
if let Some(Tok::Op('-')) = t_it.peek() {
t_it.next().unwrap();
sign = -1;
}
if let Some(Tok::Op('+')) = t_it.peek() {
t_it.next().unwrap();
}
if let Tok::Num(x) = t_it.next().unwrap() {
numerator = x;
} else {
panic!();
}
if let Tok::Op('/') = t_it.next().unwrap() {
} else {
panic!();
}
if let Tok::Num(y) = t_it.next().unwrap() {
denominator = y;
} else {
panic!();
}
fractions.push(Fraction::new(sign, numerator, denominator));
}
while fractions.len() > 1 {
let a = fractions.pop().unwrap();
let b = fractions.pop().unwrap();
let c = a.add(b);
fractions.push(c);
}
let mut res = fractions.pop().unwrap();
res = res.reduce();
res.to_string()
}
}
#[test]
fn test() {
let expression = "-1/2+1/2".to_string();
let res = "0/1".to_string();
assert_eq!(Solution::fraction_addition(expression), res);
let expression = "-1/2+1/2+1/3".to_string();
let res = "1/3".to_string();
assert_eq!(Solution::fraction_addition(expression), res);
let expression = "1/3-1/2".to_string();
let res = "-1/6".to_string();
assert_eq!(Solution::fraction_addition(expression), res);
let expression = "5/3+1/3".to_string();
let res = "2/1".to_string();
assert_eq!(Solution::fraction_addition(expression), res);
}
// Accepted solution for LeetCode #592: Fraction Addition and Subtraction
// Auto-generated TypeScript example from java.
function exampleSolution(): void {
}
// Reference (java):
// // Accepted solution for LeetCode #592: Fraction Addition and Subtraction
// class Solution {
// public String fractionAddition(String expression) {
// int x = 0, y = 6 * 7 * 8 * 9 * 10;
// if (Character.isDigit(expression.charAt(0))) {
// expression = "+" + expression;
// }
// int i = 0, n = expression.length();
// while (i < n) {
// int sign = expression.charAt(i) == '-' ? -1 : 1;
// ++i;
// int j = i;
// while (j < n && expression.charAt(j) != '+' && expression.charAt(j) != '-') {
// ++j;
// }
// String s = expression.substring(i, j);
// String[] t = s.split("/");
// int a = Integer.parseInt(t[0]), b = Integer.parseInt(t[1]);
// x += sign * a * y / b;
// i = j;
// }
// int z = gcd(Math.abs(x), y);
// x /= z;
// y /= z;
// return x + "/" + y;
// }
//
// private int gcd(int a, int b) {
// return b == 0 ? a : gcd(b, a % b);
// }
// }
Use this to step through a reusable interview workflow for this problem.
Simulate the process step by step — multiply n times, check each number up to n, or iterate through all possibilities. Each step is O(1), but doing it n times gives O(n). No extra space needed since we just track running state.
Math problems often have a closed-form or O(log n) solution hidden behind an O(n) simulation. Modular arithmetic, fast exponentiation (repeated squaring), GCD (Euclidean algorithm), and number theory properties can dramatically reduce complexity.
Review these before coding to avoid predictable interview regressions.
Wrong move: Temporary multiplications exceed integer bounds.
Usually fails on: Large inputs wrap around unexpectedly.
Fix: Use wider types, modular arithmetic, or rearranged operations.