9.30 组合数学
lc150
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> nums; // 存储数字的栈
int num1; // 进行运算的数字1
int num2; // 进行运算的数字2
for(string t: tokens){
if(t == "+" || t == "-" || t == "*" || t == "/"){
// 当前字符串是运算符,从栈中依次弹出两个数进行运算,并将运算结果入栈
num1 = nums.top();
nums.pop();
num2 = nums.top();
nums.pop();
if(t == "+")nums.push(num2 + num1);
else if(t == "-")nums.push(num2 - num1);
else if(t == "*")nums.push(num2 * num1);
else{nums.push(num2 / num1);}
}
else{
// 当前字符是数字,转为数字直接入栈
nums.push((atoi(t.c_str())));
}
}
return nums.top(); // 最终栈内留的唯一数字即为结果
}
};
递归版
class Solution {
public:
int i = 0;
int evalRPN(vector<string>& tokens) {
i = tokens.size() - 1;
return eval(tokens);
}
bool isOp(string& token) {
return token == "+" || token == "-" || token == "*" || token == "/";
}
int eval(vector<string>& tokens)
{
if (isOp(tokens[i])) {
string op = tokens[i--];
int right = eval(tokens);
int left = eval(tokens);
int ans = 0;
if (op == "+") ans = left + right;
if (op == "-") ans = left - right;
if (op == "*") ans = left * right;
if (op == "/") ans = left / right;
return ans;
}
return stoi(tokens[i--]);
}
};
lc2221
预处理阶乘、逆元及质因子幂次
组合数计算数组的“三角形和”
用数学公式快速算出类似杨辉三角加权求和的结果,核心是解决计算中除法和末尾0的问题
const int MOD = 10;
const int MX = 1000;
const int POW2[4] = {2, 4, 8, 6};
// 计算组合数,需要计算阶乘及其逆元
int f[MX + 1]; // f[n] = n!
int inv_f[MX + 1]; // invF[n] = n!^-1
int p2[MX + 1]; // n! 中的 2 的幂次
int p5[MX + 1]; // n! 中的 5 的幂次
int qpow(int x, int n) {
int res = 1;
while (n > 0) {
if (n % 2 > 0) {
res = res * x % MOD;
}
x = x * x % MOD;
n /= 2;
}
return res;
}
auto init = []() {
f[0] = inv_f[0] = 1;
for (int i = 1; i <= MX; i++) {
int x = i;
// 分离质因子 2,计算 2 的幂次
int e2 = countr_zero((uint32_t) x);
x >>= e2;
// 分离质因子 5,计算 5 的幂次
int e5 = 0;
while (x % 5 == 0) {
e5++;
x /= 5;
}
f[i] = f[i - 1] * x % MOD;
inv_f[i] = qpow(f[i], 3); // 欧拉定理求逆元
p2[i] = p2[i - 1] + e2;
p5[i] = p5[i - 1] + e5;
}
return 0;
}();
int comb(int n, int k) {
int e2 = p2[n] - p2[k] - p2[n - k];
return f[n] * inv_f[k] * inv_f[n - k] *
(e2 ? POW2[(e2 - 1) % 4] : 1) *
(p5[n] - p5[k] - p5[n - k] ? 5 : 1) % MOD;
}
class Solution {
public:
int triangularSum(vector<int>& nums) {
int n = nums.size();
int ans = 0;
for (int i = 0; i < n; i++) {
ans += comb(n - 1, i) * nums[i];
}
return ans % MOD;
}
};