周末给老婆过生日去啦,赛后补一把题~
2138. 将字符串拆分为若干长度为 k 的组
思路:模拟
时间复杂度:
按照题意即可,就不赘述啦。
class Solution {
public:
vector<string> divideString(string s, int k, char fill) {
std::vector<std::string> anw;
int i = 0;
for (; i+k < s.size(); i += k) {
anw.push_back(s.substr(i,k));
}
if (i != s.size()) {
anw.push_back(s.substr(i));
anw.back() += std::string(k-(s.size()-i), fill);
}
return anw;
}
};
2139. 得到目标值的最少行动次数
思路:逆向模拟,贪心
时间复杂度:
此题的关键在于让 次乘法发挥最大作用。
设最后一次使用乘法必然时值为 ,则 必然满足:
- 且
只有这样才能使最后一次乘法发挥最大作用。同理,设使用倒数第二次乘法时值为 ,也必有:
- 且
依次类推。不难想到,将乘法转换为除法,将加法转换为减法更易找到这些临界值。
比如,,,依次类推。
class Solution {
public:
int minMoves(int target, int maxDoubles) {
int cnt = 0;
while (target != 1) {
// 能除则除
if (--maxDoubles >= 0) {
// (target&1):余数部分只能做减法了
// 1:做一次除法
cnt += (target&1) + 1;
target /= 2;
continue;
}
// 不能则减
cnt += target - 1;
target = 1;
}
return cnt;
}
};
2140. 解决智力问题
思路:递推
时间复杂度:
设有一维数组 , 表示在题目 可自由处理的前提下后 道题的最高得分。对应题目的 的策略, 有以下几种取值。
- 做第 道题,则
- 不做第 到题,则
其中, 表示第 到题的得分, 表示做完 题需跳过的数目。
class Solution {
public:
long long mostPoints(vector<vector<int>>& questions) {
vector<int64_t> score(questions.size(), 0);
for (int i = questions.size()-1; i >= 0; i--) {
int64_t gain = questions[i][0];
int64_t skip = questions[i][1];
if (i + skip + 1 < score.size()) {
score[i] = max(score[i+1], gain + score[i+skip+1]);
} else if (i + 1 < score.size()){
score[i] = max(score[i+1], gain);
} else {
score[i] = gain;
}
}
return score[0];
}
};
2141. 同时运行 N 台电脑的最长时间
思路:二分
时间复杂度:, 为电池数量, 为总电量。
假设最长能运行 分钟,则运行 , 分钟必然都有可行方案,因此可以二分答案。
那么问题变成了,对于给定的 ,如何判断是否存在方案。
考虑给定的 ,第 节电池最多供电 分钟。如果 ,则方案必然存在,反之则必然不存在。
class Solution {
public:
long long maxRunTime(int n, vector<int>& batteries) {
int64_t left = 0, right = 0;
for (auto b : batteries) {
right += b;
}
while (left <= right) {
auto mid = (left + right) / 2;
int64_t sum = 0;
for (auto b : batteries) {
sum += min(int64_t(b), mid);
}
if (sum >= n * mid) {
left = mid + 1;
}
else {
right = mid - 1;
}
}
return left-1;
}
};