LeetCode 2024/5 每日一题 合集
2024-5-6 1463. 摘樱桃 II
代码实现
class Solution {
public:
int cherryPickup(vector<vector<int>>& grid) {
int n = size(grid), m = size(grid[0]);
std::vector f(n, std::vector(m, std::vector(m, -1)));
auto dfs = [&](auto &&self, int x, int ya, int yb) ->int {
int& u = f[x][ya][yb];
if (u != -1) return u;
u = grid[x][ya] + (ya != yb ? grid[x][yb] : 0);
for (int fa = ya - 1; fa <= ya + 1; ++fa) {
for (int fb = yb - 1; fb <= yb + 1; ++fb) {
if (fa < m && fb < m && x + 1 < n && fa >= 0 && fb >= 0) {
u = std::max(u, self(self, x + 1, fa, fb) + grid[x][ya] + (ya != yb ? grid[x][yb] : 0));
}
}
}
return u;
};
return dfs(dfs, 0, 0, m - 1);
}
};
2024-5-7 2079. 给植物浇水
代码实现
class Solution {
public:
int wateringPlants(vector<int>& plants, int capacity) {
int n = size(plants), ans = 0;
for (int i = 0; i < n; ++i) {
int j = i, s = capacity;
while (j < n && s - plants[j] >= 0) {
s -= plants[j++];
}
ans += j + j * (j != n);
i = j - 1;
}
return ans;
}
};
2024-5-8 2105. 给植物浇水 II
代码实现
class Solution {
public:
int minimumRefill(vector<int>& plants, int capacityA, int capacityB) {
int n = size(plants);
int l = 0, r = n - 1, ans = 0;
int A = capacityA, B = capacityB;
while (l <= r) {
if (A >= plants[l]) {
A -= plants[l++];
} else {
if (l == r && B >= plants[l]) {
break;
}
A = capacityA - plants[l++];
ans += 1;
}
if (l > r) break;
if (B >= plants[r]) {
B -= plants[r--];
} else {
B = capacityB - plants[r--];
ans += 1;
}
}
return ans;
}
};
2024-5-9 2960. 统计已测试设备
代码实现
class Solution {
public:
int countTestedDevices(vector<int>& b) {
int n = size(b), ans = 0;
for (int i = 0; i < n; ++i) {
if (b[i] > 0) {
for (int j = i + 1; j < n; ++j) {
b[j] -= 1;
}
ans += 1;
}
}
return ans;
}
};
2024-5-10 2391. 收集垃圾的最少总时间
代码实现
class Solution {
public:
int garbageCollection(vector<string>& garbage, vector<int>& travel) {
int n = size(garbage);
std::vector<int> pre(n);
for (int i = 1; i < n; ++i) {
pre[i] = pre[i - 1] + travel[i - 1];
}
int ans = 0;
for (auto x : "MPG") {
int sum = 0, last = 0;
for (int i = 0; i < n; ++i) {
int cnt = std::count(garbage[i].begin(), garbage[i].end(), x);
if (cnt > 0) last = i;
sum += cnt;
}
ans += pre[last] + sum;
}
return ans;
}
};
2024-5-11 1553. 吃掉 N 个橘子的最少天数
代码实现
class Solution {
public:
int minDays(int n) {
std:queue<int> q;
q.emplace(n);
std::unordered_map<int, int> mp;
while (size(q)) {
auto u = q.front();
q.pop();
if (u == 0) return mp[u];
int num = mp[u];
if (u % 2 == 0) {
if (!mp.count(u / 2)) {
q.emplace(u / 2);
mp[u / 2] = num + 1;
}
}
if (u % 3 == 0) {
if (!mp.count(u - 2 * (u / 3))) {
q.emplace(u - 2 * (u / 3));
mp[u - 2 * (u / 3)] = num + 1;
}
}
if (!mp.count(u - 1)) {
mp[u - 1] = num + 1;
q.emplace(u - 1);
}
}
return mp[0];
}
};
2024-5-12 994. 腐烂的橘子
代码实现
class Solution {
public:
int orangesRotting(vector<vector<int>>& grid) {
int n = size(grid), m = size(grid[0]);
int ans = 0;
auto work = [&](int x, int y) {
for (auto [fx, fy] : {std::pair{x + 1, y}, {x - 1, y}, {x, y + 1}, {x, y - 1}}) {
if (fx >= 0 && fy >= 0 && fx < n && fy < m && grid[fx][fy] == 1) {
grid[fx][fy] = 2;
}
}
};
while (true) {
ans += 1;
auto f = grid;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) if (f[i][j] == 2) {
work(i, j);
}
}
if (grid == f) {
break;
}
}
int sum = 0;
for (int i = 0; i < n; ++i) {
sum += std::count(grid[i].begin(), grid[i].end(), 1);
}
return sum ? -1 : ans - 1;
}
};
2024-5-13 2244. 完成所有任务需要的最少轮数
代码实现
class Solution {
public:
int minimumRounds(vector<int>& tasks) {
std::map<int, int> mp;
for (int i = 0; i < size(tasks); ++i) {
mp[tasks[i]] += 1;
}
int ans = 0;
for (auto [_, cnt] : mp) {
if (cnt == 1) return -1;
ans += cnt / 3 + (cnt % 3 != 0);
}
return ans;
}
};
2024-5-14 2589. 完成所有任务的最少时间
代码实现
class Solution {
public:
int findMinimumTime(vector<vector<int>>& tasks) {
std::sort(tasks.begin(), tasks.end(),
[&](std::vector<int>& x, std::vector<int>& y) {
return x[1] < y[1];
});
std::vector<int> run(tasks.rbegin()[0][1] + 1);
int ans = 0;
for (auto task : tasks) {
int dur = task[2];
dur -= std::accumulate(run.begin() + task[0], run.begin() + task[1] + 1, 0LL);
ans += std::max(dur, 0);
for (int i = task[1]; i >= 0 && dur > 0; --i) if (run[i] == 0) {
dur--;
run[i] = 1;
}
}
return ans;
}
};
2024-5-15 1953. 你可以工作的最大周数
代码实现
class Solution {
public:
long long numberOfWeeks(vector<int>& milestones) {
long long sum = std::accumulate(milestones.begin(), milestones.end(), 0LL);
long long max = std::ranges::max(milestones);
return max > sum - max + 1 ? (sum - max) * 2 + 1 : sum;
}
};
2024-5-16 826. 安排工作以达到最大收益
分析
每个工人最多只能安排一个工作,但是一个工作可以完成多次,则对工作收益进行排序,尽量让工人工作收益最高的工作,用multiset维护即可
代码实现
class Solution {
public:
int maxProfitAssignment(vector<int>& difficulty, vector<int>& profit, vector<int>& worker) {
int n = size(difficulty), m = size(worker);
std::vector<int> ord(n);
std::iota(ord.begin(), ord.end(), 0);
std::sort(ord.begin(), ord.end(),
[&](int x, int y){
return profit[x] > profit[y];
});
std::multiset<int> st = {worker.begin(), worker.end()};
int ans = 0;
for (int i = 0; i < n && size(st); ) {
auto it = st.lower_bound(difficulty[ord[i]]);
if (it == st.end()) {
++i;
} else {
st.erase(it);
ans += profit[ord[i]];
}
}
return ans;
}
};
2024-5-17 2644. 找出可整除性得分最大的整数
代码实现
class Solution {
public:
int maxDivScore(vector<int>& nums, vector<int>& divisors) {
std::sort(divisors.begin(), divisors.end());
int max = 0, ans = divisors[0];
for (int i = 0; i < size(divisors); ++i) {
int tot = 0;
for (int j = 0; j < size(nums); ++j) {
tot += nums[j] % divisors[i] == 0;
}
if (tot > max) {
max = tot, ans = divisors[i];
}
}
return ans;
}
};
2024-5-18 1535. 找出数组游戏的赢家
代码实现
class Solution {
public:
int getWinner(vector<int>& arr, int k) {
int n = size(arr);
int win = arr[0], cnt = 0;
for (int i = 0; i < n; ++i) {
int j = i + 1;
while (j < n && arr[j] < win) {
j += 1, cnt += 1;
}
if (cnt >= k) {
return win;
} else {
win = arr[j], cnt = 1;
}
i = j - 1;
}
return std::ranges::max(arr);
}
};
2024-5-19 1542. 找出最长的超赞子字符串
分析
可以发现存在超赞子字符串的条件是,字符出现的次数为奇数的数量
代码实现
class Solution {
public:
int longestAwesome(string s) {
int n = size(s);
std::vector<std::array<int, 10>> pre(n + 1);
std::map<int, int> mp{{0, 0}};
int ans = 1;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < 10; ++j) {
pre[i + 1][j] = pre[i][j] + (s[i] - '0' == j);
}
int u = 0;
for (int j = 0; j < 10; ++j) {
u += (pre[i + 1][j] & 1) << j;
}
for (int j = 0; j < 10; ++j) {
int v = 1 << j;
if (mp.count(u ^ v)) {
ans = std::max(ans, i - mp[u ^ v] + 1);
}
}
if (!mp.count(u)) {
mp[u] = i + 1;
}
ans = std::max(ans, i - mp[u] + 1);
}
return ans;
}
};
2024-5-20 2769. 找出最大的可达成数字
代码实现
class Solution {
public:
int theMaximumAchievableX(int num, int t) {
return num + 2 * t;
}
};
2024-5-21 2225. 找出输掉零场或一场比赛的玩家
代码实现
class Solution {
public:
vector<vector<int>> findWinners(vector<vector<int>>& matches) {
std::map<int, int> lose;
for (auto who : matches) {
lose[who[1]] += 1, lose[who[0]] += 0;
}
std::vector<std::vector<int>> answer(2);
for (auto [x, c] : lose) if (c <= 1) {
answer[c].emplace_back(x);
}
return answer;
}
};
2024-5-22 2831. 找出最长等值子数组(双指针)
代码实现
class Solution {
public:
int longestEqualSubarray(vector<int>& nums, int k) {
int n = size(nums);
std::vector<int> cnt(n + 1);
int ans = 1, l = 0;
for (int r = 0; r < n; ++r) {
cnt[nums[r]]++;
while (r - l + 1 - cnt[nums[l]] > k) {
cnt[nums[l++]]--;
}
ans = std::max(ans, cnt[nums[l]]);
}
for (int i = l; i < n; ++i) {
ans = std::max(ans, cnt[nums[i]]);
}
return ans;
}
};
2024-5-23 1673. 找出最具竞争力的子序列
分析
每次查询[i + 1, n - (k - ans.size())]的最小值,如果此时
代码实现
template<class T,
class Cmp = std::less<T>>
struct RMQ {
const Cmp cmp = Cmp();
static constexpr unsigned B = 64;
using u64 = unsigned long long;
int n;
std::vector<std::vector<T>> a;
std::vector<T> pre, suf, ini;
std::vector<u64> stk;
RMQ() {}
RMQ(const std::vector<T> &v) {
init(v);
}
void init(const std::vector<T> &v) {
n = v.size();
pre = suf = ini = v;
stk.resize(n);
if (!n) return;
const int M = (n - 1) / B + 1;
const int lg = std::__lg(M);
a.assign(lg + 1, std::vector<T>(M));
for (int i = 0; i < M; ++i) {
a[0][i] = v[i * B];
for (int j = 1; j < B && i * B + j < n; ++j) {
a[0][i] = std::min(a[0][i], v[i * B + j], cmp);
}
}
for (int i = 1; i < n; ++i) {
if (i % B) {
pre[i] = std::min(pre[i], pre[i - 1], cmp);
}
}
for (int i = n - 2; i >= 0; --i) {
if (i % B != B - 1) {
suf[i] = std::min(suf[i], suf[i + 1], cmp);
}
}
for (int j = 0; j < lg; ++j) {
for (int i = 0; i + (2 << j) <= M; ++i) {
a[j + 1][i] = std::min(a[j][i], a[j][i + (1 << j)], cmp);
}
}
for (int i = 0; i < M; ++i) {
const int l = i * B;
const int r = std::min(1U * n, l + B);
u64 s = 0;
for (int j = l; j < r; ++j) {
while (s && cmp(v[j], v[std::__lg(s) + l])) {
s ^= 1ULL << std::__lg(s);
}
s |= 1ULL << (j - l);
stk[j] = s;
}
}
}
T operator()(int l, int r) { // [l, r)
if (l / B != (r - 1) / B) {
T ans = std::min(suf[l], pre[r - 1], cmp);
l = l / B + 1;
r = r / B;
if (l < r) {
int k = std::__lg(r - l);
ans = std::min({ans, a[k][l], a[k][r - (1 << k)]}, cmp);
}
return ans;
} else {
int x = B * (l / B);
return ini[__builtin_ctzll(stk[r - 1] >> (l - x)) + l];
}
}
};
class Solution {
public:
vector<int> mostCompetitive(vector<int>& nums, int k) {
int n = size(nums);
RMQ rmq(nums);
std::vector<int> ans;
for (int i = 0; i < n && size(ans) < k; ++i) {
if (nums[i] <= rmq(i, std::min<int>(n - (k - size(ans)) + 1, n))) {
ans.emplace_back(nums[i]);
}
}
return ans;
}
};
2024-5-24 2831. 找出最长等值子数组
代码实现
class Solution {
public:
int longestEqualSubarray(vector<int>& nums, int k) {
int n = size(nums);
std::vector<int> cnt(n + 1);
int ans = 1, l = 0;
for (int r = 0; r < n; ++r) {
cnt[nums[r]]++;
while (r - l + 1 - cnt[nums[l]] > k) {
cnt[nums[l++]]--;
}
ans = std::max(ans, cnt[nums[l]]);
}
for (int i = l; i < n; ++i) {
ans = std::max(ans, cnt[nums[i]]);
}
return ans;
}
};
2024-5-25 2903. 找出满足差值条件的下标 I
代码实现
class Solution {
public:
vector<int> findIndices(vector<int>& nums, int indexDifference, int valueDifference) {
int n = size(nums);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (abs(i - j) >= indexDifference && abs(nums[i] - nums[j]) >= valueDifference) {
return {i, j};
}
}
}
return {-1, -1};
}
};
2024-5-26 1738. 找出第 K 大的异或坐标值
分析
即求前k大的前缀异或值
代码实现
class Solution {
public:
int kthLargestValue(vector<vector<int>>& matrix, int k) {
int n = size(matrix), m = size(matrix[0]);
std::vector<int> ans;
std::vector<std::vector<int>> pre(n + 1, std::vector<int>(m + 1));
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
pre[i][j] = pre[i - 1][j] ^ pre[i][j - 1] ^ pre[i - 1][j - 1] ^ matrix[i - 1][j - 1];
ans.emplace_back(pre[i][j]);
}
}
std::sort(ans.rbegin(), ans.rend());
return ans[k - 1];
}
};
2024-5-27 2028. 找出缺失的观测数据
代码实现
class Solution {
public:
vector<int> missingRolls(vector<int>& rolls, int mean, int n) {
int m = size(rolls), sum = std::accumulate(rolls.begin(), rolls.end(), 0);
int res = mean * (n + m) - sum;
std::vector<int> ans(n, res / n);
res -= res / n * n;
for (int i = 0; i < n && res; res--, ++i) {
ans[i] += 1;
}
if (std::accumulate(ans.begin(), ans.end(), 0) + sum != mean * (n + m) || ans[0] > 6 || ans.back() < 1) {
return {};
}
return ans;
}
};
2024-5-28 2951. 找出峰值
代码实现
class Solution {
public:
vector<int> findPeaks(vector<int>& mountain) {
std::vector<int> ans;
for (int i = 1; i < size(mountain) - 1; ++i) {
if (mountain[i] > mountain[i - 1] && mountain[i] > mountain[i + 1]) {
ans.emplace_back(i);
}
}
return ans;
}
};
2024-5-29 2981. 找出出现至少三次的最长特殊子字符串 I
分析
代码实现
class Solution {
public:
int maximumLength(string s) {
std::unordered_map<std::string, int> mp;
for (int i = 0; i < size(s); ++i) {
std::string k;
for (int j = i; j < size(s); ++j) {
k += s[j];
mp[k] += 1;
}
}
int len = -1;
for (auto [x, cnt] : mp) {
if (cnt >= 3 && std::count(x.begin(), x.end(), x[0]) == size(x)) {
len = std::max<int>(len, size(x));
}
}
return len;
}
};
2024-5-30 2982. 找出出现至少三次的最长特殊子字符串 II
分析
发现
代码实现
class Solution {
public:
int maximumLength(string s) {
std::vector<std::vector<int>> len(26);
for (int i = 0; i < size(s); ++i) {
int j = i + 1;
while (j < size(s) && s[i] == s[j]) {
j += 1;
}
len[s[i] - 'a'].emplace_back(j - i);
i = j - 1;
}
int ans = -1;
for (int i = 0; i < 26; ++i) {
std::sort(len[i].rbegin(), len[i].rend());
if (size(len[i]) >= 3) {
ans = std::max(ans, len[i][2]);
}
if (size(len[i]) >= 2 && len[i][1] + len[i][0] >= 3) {
if (len[i][0] == len[i][1] + 1) {
ans = std::max(ans, len[i][1]);
} else if (len[i][0] >= len[i][1] + 2) {
ans = std::max(ans, len[i][0] - 2);
} else {
ans = std::max(ans, len[i][1] - 1);
}
}
if (size(len[i]) >= 1 && len[i][0] >= 3) {
ans = std::max(ans, len[i][0] - 2);
}
}
return ans;
}
};
2024-5-31 2965. 找出缺失和重复的数字
代码实现
class Solution {
public:
vector<int> findMissingAndRepeatedValues(vector<vector<int>>& grid) {
int n = size(grid);
std::vector<int> cnt(n * n + 1);
std::vector<int> ans(2);
for (int i = 0; i < size(grid); ++i) {
for (int j = 0; j < size(grid[i]); ++j) {
cnt[grid[i][j]] += 1;
}
}
for (int i = 1; i <= n * n; ++i) {
if (cnt[i] == 0) {
ans[1] = i;
}
if (cnt[i] == 2) {
ans[0] = i;
}
}
return ans;
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?