第一题
题目:
解法:正常的做法是三重循环,不过可以进行优化。将数组进行排列,对于某个值的数,他的贡献值=自身的个数×比自己小的数的个数×比自己大的数的个数。
第二题
题目:
解法:这道题有个陷阱。很多人看到搜索二叉树直接在树中进行了大小比较(通常来说logn的),但是但树只剩下一条链表(即每个节点只有左子树或右子树)时时间复杂度就来到了O(n)。所以先中序遍历拿出排序后的数组之后用二分搜索即可。
第三题
题目:
解法:这道题需要转换思路。我们不应该去纠结如何分配车辆,因为不管怎么说车辆肯定是够的(每个城市都有一辆车),不存在人多到车坐不下的情况。在这个假设下,我们从边缘向0逼近。假设有对于0节点的一条子树上总共有n个人,那么这n个人到0节点必定最少会花费ceil(n/size)的油费,在此基础上向外部节点进行递归。
class Solution {
public:
long long minimumFuelCost(vector<vector<int>>& roads, int seats) {
int n = roads.size() + 1;
vector<vector<int>> g(n);
for(auto& v : roads){
int f = v[0], t = v[1];
g[f].emplace_back(t);
g[t].emplace_back(f);
}
long long ans = 0;
function<int(int, int)> dfs = [&](int o, int p)-> int {
int size = 1;
for(auto i : g[o]){
if(i == p) continue;
size += dfs(i, o);
}
if(o != 0) ans += (size + seats - 1) / seats;
return size;
};
dfs(0, -1);
return ans;
}
};
第四题
题目:
解法:定义 f[i][j]表示把 s的前 j 个字符分割成 i段的方案数(每段需要满足题目的后两个要求)。
即 s[j]不是质数且 s[j+1] 是质数。
如果 j是分割点,那么可以考虑枚举第 i−1段与第 ii段的分割点 j’,需满足 j−j′≥minLength。
累加所有 f[i−1][j′],记作 sum,那么 f[i][j]=sum。
每个 f[i][j]都要循环累加复杂度过高。考虑到 j−j′≥minLength,我们可以从小到大同时遍历 j′和 j,一边更新 sum,一边计算 f[i][j]。
primes = {'2', '3', '5', '7'}
mod = 10 ** 9 + 7
class Solution:
def beautifulPartitions(self, s: str, k: int, minLength: int) -> int:
n = len(s)
# 剪枝
if minLength * k > n or s[0] not in primes or s[-1] in primes:
return 0
f = [[0] * (n + 1) for _ in range(k + 1)]
f[0][0] = 1
for i in range(1, k + 1):
tot = 0
for j in range(minLength * i, n + 1):
# 统计j前面所有可以累加的j0
j0 = j - minLength + 1
if s[j0 - 1] in primes:
# 用tot更新前缀和
tot = (tot + f[i - 1][j0 - 1]) % mod
if s[j - 1] not in primes:
f[i][j] = tot
return f[k][n]
以上题解只是对灵神题解的总结,非原创捏1