comments | difficulty | edit_url | rating | source | tags | |||
---|---|---|---|---|---|---|---|---|
true |
中等 |
1407 |
第 127 场周赛 Q2 |
|
通常,正整数 n
的阶乘是所有小于或等于 n
的正整数的乘积。例如,factorial(10) = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1
。
相反,我们设计了一个笨阶乘 clumsy
:在整数的递减序列中,我们以一个固定顺序的操作符序列来依次替换原有的乘法操作符:乘法(*),除法(/),加法(+)和减法(-)。
例如,clumsy(10) = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1
。然而,这些运算仍然使用通常的算术运算顺序:我们在任何加、减步骤之前执行所有的乘法和除法步骤,并且按从左到右处理乘法和除法步骤。
另外,我们使用的除法是地板除法(floor division),所以 10 * 9 / 8
等于 11
。这保证结果是一个整数。
实现上面定义的笨函数:给定一个整数 N
,它返回 N
的笨阶乘。
示例 1:
输入:4 输出:7 解释:7 = 4 * 3 / 2 + 1
示例 2:
输入:10 输出:12 解释:12 = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1
提示:
1 <= N <= 10000
-2^31 <= answer <= 2^31 - 1
(答案保证符合 32 位整数。)
笨阶乘的计算过程可以看作是一个栈的模拟过程。
我们定义一个栈 stk
,初始时我们将
然后我们从
- 当
$k = 0$ 时,表示乘法操作,我们将栈顶元素出栈,与$x$ 相乘后再入栈; - 当
$k = 1$ 时,表示除法操作,我们将栈顶元素出栈,与$x$ 相除后取整数部分再入栈; - 当
$k = 2$ 时,表示加法操作,我们直接将$x$ 入栈; - 当
$k = 3$ 时,表示减法操作,我们将$-x$ 入栈。
接着我们更新
最后,我们将栈中的元素累加即为答案。
时间复杂度
class Solution:
def clumsy(self, n: int) -> int:
k = 0
stk = [n]
for x in range(n - 1, 0, -1):
if k == 0:
stk.append(stk.pop() * x)
elif k == 1:
stk.append(int(stk.pop() / x))
elif k == 2:
stk.append(x)
else:
stk.append(-x)
k = (k + 1) % 4
return sum(stk)
class Solution {
public int clumsy(int n) {
Deque<Integer> stk = new ArrayDeque<>();
stk.push(n);
int k = 0;
for (int x = n - 1; x > 0; --x) {
if (k == 0) {
stk.push(stk.pop() * x);
} else if (k == 1) {
stk.push(stk.pop() / x);
} else if (k == 2) {
stk.push(x);
} else {
stk.push(-x);
}
k = (k + 1) % 4;
}
return stk.stream().mapToInt(Integer::intValue).sum();
}
}
class Solution {
public:
int clumsy(int n) {
stack<int> stk;
stk.push(n);
int k = 0;
for (int x = n - 1; x; --x) {
if (k == 0) {
stk.top() *= x;
} else if (k == 1) {
stk.top() /= x;
} else if (k == 2) {
stk.push(x);
} else {
stk.push(-x);
}
k = (k + 1) % 4;
}
int ans = 0;
while (!stk.empty()) {
ans += stk.top();
stk.pop();
}
return ans;
}
};
func clumsy(n int) (ans int) {
stk := []int{n}
k := 0
for x := n - 1; x > 0; x-- {
switch k {
case 0:
stk[len(stk)-1] *= x
case 1:
stk[len(stk)-1] /= x
case 2:
stk = append(stk, x)
case 3:
stk = append(stk, -x)
}
k = (k + 1) % 4
}
for _, x := range stk {
ans += x
}
return
}
function clumsy(n: number): number {
const stk: number[] = [n];
let k = 0;
for (let x = n - 1; x; --x) {
if (k === 0) {
stk.push(stk.pop()! * x);
} else if (k === 1) {
stk.push((stk.pop()! / x) | 0);
} else if (k === 2) {
stk.push(x);
} else {
stk.push(-x);
}
k = (k + 1) % 4;
}
return stk.reduce((acc, cur) => acc + cur, 0);
}