第 48 场双周赛
Problem A - 字符串中第二大的数字
模拟即可。
- 时间复杂度。
- 空间复杂度。
注意这里最多10个数字,所以可以认为set
操作的时间复杂度为常数。
参考代码(C++)
class Solution {
public:
int secondHighest(string s) {
set<int> st;
for (char c : s)
if ('0' <= c && c <= '9')
st.insert(c - '0');
if (st.size() < 2)
return -1;
return *prev(prev(st.end()));
}
};
如果用Python的话一行就可以搞定。
参考代码(Python 3)
class Solution:
def secondHighest(self, s: str) -> int:
v = sorted(list(set(map(int, (filter(lambda x: x.isnumeric(), list(s)))))), reverse=True)
return -1 if len(v) < 2 else v[1]
Problem B - 设计一个验证系统
理解题意后直接模拟即可。
- 生成和更新操作的时间复杂度为,计数操作的时间复杂度为。
- 空间复杂度。
参考代码(C++)
class AuthenticationManager {
int timeToLive;
unordered_map<string, int> mp;
public:
AuthenticationManager(int timeToLive): timeToLive(timeToLive) {}
void generate(string tokenId, int currentTime) {
mp[tokenId] = currentTime + timeToLive;
}
void renew(string tokenId, int currentTime) {
if (mp.count(tokenId) && mp[tokenId] > currentTime)
mp[tokenId] = currentTime + timeToLive;
}
int countUnexpiredTokens(int currentTime) {
int ans = 0;
for (auto [key, expirationTime] : mp)
if (expirationTime > currentTime)
ans++;
return ans;
}
};
Problem C - 你能构造出连续值的最大数目
如果做过LC330 - 按要求补齐数组,那么本题就非常简单了。
显然,我们应当从最小的数字开始——所以要对原数组进行排序。
如果当前最大表示到,此时数组中还未使用的最小元素为
- 如果,那么我们无论如何也表示不出,结束求解。
- 如果,由于我们已经能表示,则在使用后一定可以表示,所以我们进行更新,继续求解。
时间复杂度。
空间复杂度。
参考代码(C++)
class Solution {
public:
int getMaximumConsecutive(vector<int>& coins) {
sort(coins.begin(), coins.end());
int now = 0;
for (int coin : coins) {
if (coin <= now + 1)
now += coin;
else
break;
}
return now + 1;
}
};
Problem D - N 次操作后的最大分数和
看到的取值范围就知道是Bitmask DP。预处理出所有的GCD,之后从0状态开始动态规划即可。当前的轮次可以从状态二进制中的个数求出。
- 时间复杂度。
- 空间复杂度。
参考代码(C++)
int gcd(int x, int y) {
return y == 0 ? x : gcd(y, x % y);
}
class Solution {
public:
int maxScore(vector<int>& nums) {
int n = nums.size();
vector<int> dp(1 << n, 0);
vector<vector<int>> g(n, vector<int>(n));
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
g[i][j] = gcd(nums[i], nums[j]);
for (int state = 0; state < (1 << n); ++state) {
int cnt = __builtin_popcount(state);
if (cnt & 1)
continue;
int now = cnt / 2 + 1;
for (int i = 0; i < n; ++i)
for (int j = i + 1; j < n; ++j) {
if ((state & (1 << i)) || (state & (1 << j)))
continue;
int nxt = state | (1 << i) | (1 << j);
dp[nxt] = max(dp[nxt], dp[state] + g[i][j] * now);
}
}
return dp.back();
}
};