An algorithms/LeetCode-oriented question.
Problem description:
Given a string expression, evaluate it and output the arithmetic result.
Restrictions and constraints:
Only positive integers are supported.
Intermediate-state validation:
At
any stage
of the calculation, if a negative number appears (for example, an intermediate result below 0) or a non-integer appears (for example, division that produces a decimal or fraction), stop immediately and return False.
Test cases (Examples):
Input "(3 + (3 * 5)) / 2" -> return 9.
Input "((3 - 5) + 12) / 2" -> return False (because 3 - 5 = -2 produces a negative number partway through).
Input "8 / 12" -> return False (because 8 / 12 produces a non-integer).
Provided function:
The interviewer provided a helper split(s), which takes an expression string and returns the tuple (left_operand, operator, right_operand):
split("3 / 5") => output ("3", "/", "5")
split("5") => output ("5",)
split("(10 / 2) / 5") => output ("(10 / 2)", "/", "5")
Approach and recursive design (Python logic):
Since the interviewer directly provided the split helper to separate the expression at its outermost operator, this problem can be solved very elegantly using divide and conquer and recursion:
Base Case:
After calling split(s), if the returned tuple has length 1 (containing only one element), we've reduced it to a basic number:
Remove leading and trailing whitespace and outer parentheses.
Check whether the string consists entirely of digits. If it does and represents a positive integer, convert it to int and return it; otherwise, return False.
Recursive decomposition and evaluation (Recursive Step):
If split(s) returns (left_str, op, right_str), first recursively evaluate the left and right expressions:
left_val = evaluate(left_str)
right_val = evaluate(right_str)
If either left_val or right_val returns False (meaning the subtree evaluates to an invalid value), immediately propagate False upward.
Strict operator logic and boundary checks:
Addition (+): Return left_val + right_val.
Multiplication (*): Return left_val * right_val.
Subtraction (-): Check whether left_val - right_val <= 0. If so, the result is negative or zero (and does not meet the positive-integer requirement), so immediately return False; otherwise, return the difference.
Division (/):
First check whether the denominator right_val == 0. If it is 0, return False.
Check divisibility: left_val % right_val != 0? If there is a remainder (producing a fractional value), immediately return False; otherwise, return the integer-division result left_val // right_val.
Complexity analysis:
Time complexity: O(N⋅D), where N is the expression length and D is the expression tree's depth. The main costs are split's string processing and the recursion depth.
Space complexity:
O(D): The recursion stack depth is the expression tree's height.
Discussion
Loading comments…