The factorial of a positive integer n
is the product of all positive integers less than or equal to n
.
factorial(10) = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1
.We make a clumsy factorial using the integers in decreasing order by swapping out the multiply operations for a fixed rotation of operations with multiply '*'
, divide '/'
, add '+'
, and subtract '-'
in this order.
clumsy(10) = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1
.However, these operations are still applied using the usual order of operations of arithmetic. We do all multiplication and division steps before any addition or subtraction steps, and multiplication and division steps are processed left to right.
Additionally, the division that we use is floor division such that 10 * 9 / 8 = 90 / 8 = 11
.
Given an integer n
, return the clumsy factorial of n
.
Example 1:
Input: n = 4 Output: 7 Explanation: 7 = 4 * 3 / 2 + 1
Example 2:
Input: n = 10 Output: 12 Explanation: 12 = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1
Constraints:
1 <= n <= 104
This problem requires calculating a "clumsy factorial," a modified version of the standard factorial where the operations alternate between multiplication, division, addition, and subtraction in a specific pattern. The key is to correctly handle the order of operations (multiplication and division before addition and subtraction) and the integer division.
The most efficient approach uses a stack to simulate the calculation process. Here's a breakdown:
Initialization:
n
.k
to 0. k
will track the current operation (0: multiply, 1: divide, 2: add, 3: subtract).Iteration:
n-1
down to 1. For each number x
:
k
, perform the corresponding operation:
k=0
(multiply): Pop the top element from the stack, multiply it by x
, and push the result back onto the stack.k=1
(divide): Pop the top element, perform integer division (/
), and push the result.k=2
(add): Push x
onto the stack.k=3
(subtract): Push -x
onto the stack.k
to (k + 1) % 4
to cycle through the operations.Final Summation:
n-1
times, and each operation within the loop takes constant time. The final summation also takes linear time with respect to the size of the stack (which is at most n).n
elements.class Solution:
def clumsy(self, n: int) -> int:
stk = [n] # Initialize stack with n
k = 0 # Operation counter (0: *, 1: /, 2: +, 3: -)
for x in range(n - 1, 0, -1):
if k == 0:
stk.append(stk.pop() * x)
elif k == 1:
stk.append(stk.pop() // x) # Integer division
elif k == 2:
stk.append(x)
else:
stk.append(-x)
k = (k + 1) % 4
return sum(stk)
The code in other languages (Java, C++, Go, TypeScript) follows the same logic, using their respective stack implementations and syntax. The core algorithm remains consistent across all languages. Note the use of integer division (//
in Python, /
in Java, C++, Go, and | 0
in Typescript) to correctly handle the floor division requirement.