LeetCode 第 219 场周赛题目
???点这里看题目???
5625. 比赛中的配对次数
做法一:模拟
根据题意模拟晋级的规则,累加比赛场次。
时间复杂度: O(n)
空间复杂度: O(1)
class Solution {
public:
int numberOfMatches(int n) {
int cnt = 0;
while(n > 1) {
cnt += n/2;
n = n/2 + n%2;
}
return cnt;
}
};
做法二
分析一下,每场比赛会淘汰一支队伍,那么淘汰 N-1 支队伍需要 N-1 场比赛。
时间复杂度: O(1)
空间复杂度: O(1)
class Solution {
public:
int numberOfMatches(int n) {
return n-1;
}
};
5626. 十-二进制数的最少数目
因为没有限制十-二进制数
中 1 的个数,所以十-二进制数
的数目由 n 中最大的一位决定。
时间复杂度: O(n.size())
空间复杂度: O(1)
class Solution {
public:
int minPartitions(string n) {
return *max_element(n.begin(), n.end()) - '0';
}
};
5627. 石子游戏 VII
随着游戏进行,石头会越来越少,所以Alice的得分总是比Bob高。
假设当面临的局面为 [L,R],Alice 和 Bob 能得到的「最优」分差 分别用** adiff(L,R), bdiff(L,R)**表示。
先来看 adiff 如何推导:
- 当 L == R 时,不难发现 adiff(L,R) = 0。
- 当 L < R 时,Alice 有两种选择:
- 选择 L:Alice得分为 sum(L+1,R)。Bob 进入局面[L+1,R]。
- 选择 R:得分为sum(L,R-1),Bob 进入局面[L,R-1]。
因为Alice 要「让分差最大化」,所以Alice 面对局面[L+R] 时的最优解为:
再来看,bdiff 如何推导:
- 当 L == R 时,不难发现 bdiff(L,R) = 0。
- 当 L < R 时,Bob 同样有两种选择:
- 选择 L:Bob 得分为 sum(L+1,R)。Alice 进入局面[L+1,R]。
- 选择 R:得分为sum(L,R-1),Bob 进入局面[L,R-1]。
最关键的地方来了,Bob 是要让「分差最小化」的,那当 L < R 时,Bob 要选择分差较小的策略吗?不是的!「Bob 也要选分差较大的策略」。
因为,「Bob 是后手」,当 Bob 开始选时,「Bob 的得分总是比 Alice 低的」,所以 「Bob 要选择分差较大的策略追回比分」。这才是 Bob 「整体最优」的策略。
综上,可以得出 bdiff(L,R) 的推导方式:
基于 adiff 和 bdiff 的计算公式,可以较容易的写出递归代码啦。
时间复杂度:O(n^2)
空间复杂度:O(n^2)
class Solution {
public:
int dp[1001][1001];
int dfs(int l, int r, const vector<int> &prefix) {
if (l >= r) {
return 0;
}
if (dp[l][r] != -1) {
return dp[l][r];
}
int diff_l = prefix[r]-prefix[l] - dfs(l+1, r, prefix);
int diff_r = prefix[r-1] - prefix[l-1] - dfs(l, r-1, prefix);
return dp[l][r] = max(diff_l, diff_r);
}
int stoneGameVII(vector<int>& stones) {
vector<int> prefix(1, 0);
for (auto s : stones) {
prefix.push_back(prefix.back() + s);
}
memset(dp, -1, sizeof(dp));
return dfs(1, stones.size(), prefix);
}
};
5245. 堆叠长方体的最大高度
假设从 n 个长方体中「选取了 k 个满足堆叠要求的长方体」,则这个 k 个长方体必然可以「像套娃一样套在一起」。
这 k 个长方体中,大长方体的「三个维度都不小于」小长方体的,所以,无论「大长方体如何旋转」,「小长方体都存在一种旋转方式」可以使其堆叠到前者上(因为是套娃嘛,无论怎么转,都可以套起来)。
既然如此,这 k 个长方体「都用最长边作高」,这样「整体高度必然最大」。
那如何选取最优的 k 个长方体呢?
不难发现,如果 n 个长方体都用最长边作高,然后按照高度升序排序。那么最终答案必然是「在其中选择一个高度和最大的子序列」。
需要注意的是,高度相同的长方体的排序方式:应该保证排完之后,底面面积较大的长方体在较小的长方体的后面。这是因为在下面的长方体的底面积必然不小于上面的。
class Solution {
public:
int maxHeight(vector<vector<int>>& cuboids) {
vector<int> sum;
for (auto & c : cuboids) {
sort(c.begin(), c.end());
}
sort(cuboids.begin(), cuboids.end(), [](const auto& l, const auto& r) {
if (l[2] != r[2]) return l[2] > r[2];
return l[0] * l[1] >= r[1] * r[0]; // 比较底面积
});
for (int i = 0; i sum.emplace_back(0);
for (int j = 0; j if (cuboids[i][0] <= cuboids[j][0] && cuboids[i][1] <= cuboids[j][1]) {
sum.back() = max(sum.back(), sum[j]);
}
}
sum.back() += cuboids[i][2];
}
return *max_element(sum.begin(), sum.end());
}
};