有生之年第一场 LeetCode周赛,y神 就带我 AK 了,何其荣幸!
泪目…
100264. 最长的严格递增或递减子数组
模拟即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e6 + 10;
class Solution {
public:
int longestMonotonicSubarray(vector<int> &nums) {
int n = nums.size();
int ans = 1;
int l = 0, r = l + 1;
int c = 1;
for (int i = 1; i < n; i++) {
if (nums[i] < nums[i - 1]) {
c++;
ans = max(c,ans);
} else {
c = 1;
}
}
c = 1;
for (int i = 1; i < n; i++) {
if (nums[i] > nums[i - 1]) {
c++;
ans = max(c,ans);
} else {
c = 1;
}
}
return ans;
}
};
int main() {
Solution s;
// vector<int> nums = {1, 4, 3, 3, 2};
// vector<int> nums = {3, 3, 3, 3};
// vector<int> nums = {1, 4, 3, 3, 2};
cout << s.longestMonotonicSubarray(nums) << endl;
return 0;
}
100242. 满足距离约束且字典序最小的字符串
模拟即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e6 + 10;
// distance(s1, s2)
// calc min dis s1[i] s2[i]
// distance("ab", "cd") == 4
// distance("a", "z") == 1
// 你可以对字符串 s 执行 任意次 操作。在每次操作中,可以将 s 中的一个字母 改变 为 任意 其他小写英文字母。
// 可以得到的 字典序最小 的字符串 t ,且满足 distance(s, t) <= k
class Solution {
public:
pair<int, char> c(char &c1, int k) {
char cc;
int dis = 0;
if (c1 - 'a' < 'z' - c1 + 1) {
dis = c1 - 'a';
cc = c1 - dis;
} else {
dis = 'z' - c1 + 1;
cc = (c1 - 'a' + dis) % 26 + 'a';
}
if (k >= dis) {
return make_pair(dis, cc);
} else {
// all k
if (c1 + k < c1 - k) {
cc = c1 + k;
dis = k;
} else {
cc = c1 - k;
dis = k;
}
return make_pair(dis, cc);
}
}
string getSmallestString(string s, int k) {
for (auto &it: s) {
// using min cost to
auto [kk, cc] = c(it, k);
k -= kk;
it = cc;
if (k == 0) { break; }
}
return s;
}
};
int main() {
Solution s;
// cout << s.getSmallestString("zbbz", 3) << endl;
// cout << s.getSmallestString("xaxcd", 4) << endl;
// cout << s.getSmallestString("lol", 0) << endl;
//"rn"
//9
// r s t u v w x y z a
cout << s.getSmallestString("rn", 9) << endl;
return 0;
}
3107. 使数组中位数等于 K 的最少操作数
排序,分类讨论,都是把前面或者后面堆成 k,这样中位数就是 k
十分眼熟的题目
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
class Solution {
public:
long long minOperationsToMakeMedianK(vector<int> &nums, int k) {
sort(nums.begin(), nums.end());
int mid = nums.size() / 2;
long long ans = 0;
if (k == nums[mid]) {
return 0;
}
if (k > nums[mid]) {
for (int i = mid; i < nums.size(); ++i) {
if (nums[i] < k) {
ans += k - nums[i];
}
}
} else {
for (int i = mid; i >= 0; --i) {
if (nums[i] > k) {
ans += nums[i] - k;
}
}
}
return ans;
}
};
int main() {
Solution s;
vector<int> nums{2, 5, 6, 8, 5};
cout << s.minOperationsToMakeMedianK(nums, 4) << endl;
return 0;
}
100244. 带权图里旅途的最小代价
并查集
因为任何一个集合的与和一定是最小值,所以可以维护一个集合的最小值
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e6 + 10;
class UnionFind {
public:
vector<int> fa;
vector<int> faMin;
vector<int> faAnd;
UnionFind(int n) : fa(n), faMin(n, INT_MAX), faAnd(n, INT_MAX) {
iota(fa.begin(), fa.end(), 0); // Fill fa with 0 to n-1
}
int find(int x) {
if (fa[x] != x) {
fa[x] = find(fa[x]);
}
return fa[x];
}
void merge(int from, int to, int val) {
int x = find(from), y = find(to);
if (x == y) {
faAnd[x] &= val;
faMin[x] = min(faMin[x], val);
return;
}
fa[x] = y;
faAnd[y] = faAnd[x] & faAnd[y] & val;
faMin[y] = min({faMin[x], faMin[y], val});
}
bool same(int x, int y) {
return find(x) == find(y);
}
};
class Solution {
public:
vector<int> minimumCost(int n, vector<vector<int>>& edges, vector<vector<int>>& queries) {
UnionFind uf(n);
for (auto& e : edges) {
uf.merge(e[0], e[1], e[2]);
}
vector<int> ans(queries.size());
for (size_t i = 0; i < queries.size(); ++i) {
int x = queries[i][0], y = queries[i][1];
if (x == y) {
ans[i] = 0;
continue;
}
if (!uf.same(x, y)) {
ans[i] = -1;
continue;
}
int f = uf.find(x);
ans[i] = min(uf.faMin[f], uf.faAnd[f]);
}
return ans;
}
};
int main() {
Solution s;
vector<vector<int>> edges{{0, 1, 7},
{1, 3, 7},
{1, 2, 1}};
vector<vector<int>> query{{0, 3},
{3, 4}};
vector<int> ans = s.minimumCost(5, edges, query);
for (auto it: ans) {
cout << it << ' ';
}
return 0;
}