总结:
本周周赛难度偏易,连我都差点AK了,第四题忘记判重了,所以最后没有做出来比较可惜。前三题都比较简单,第四题思维上逆向思维,下周继续加油~争取今年有机会AK
Leetcode5859. 差的绝对值为 K 的数对数目
这道题数据范围很小,所以直接枚举就可以
class Solution {
public:
int countKDifference(vector<int>& nums, int k) {
int n = nums.size(), res = 0;
for (int i = 0; i < n; i ++ )
for (int j = i + 1; j < n; j ++ ) {
if (abs(nums[i] - nums[j]) == k)
res ++ ;
}
return res;
}
};
5860. 从双倍数组中还原原数组
比赛时提交代码:
当时思路是 h a s h hash hash存每个数个数,然后数组排序,每一次2倍的数和自己删掉,如果发现某一个数没有2倍数返回空数组
class Solution {
public:
vector<int> findOriginalArray(vector<int>& a) {
int n = a.size();
if (n & 1)
return {};
unordered_map<int, int> hash;
sort(a.begin(), a.end());
vector<int> res;
for (int i = 0; i < n; i ++ ) {
hash[a[i]] ++ ;
}
for (int i = 0; i < n; i ++ ) {
if (hash[a[i]]) {
if (hash[2 * a[i]]) {
res.push_back(a[i]);
hash[2 * a[i]] -- ;
hash[a[i]] -- ;
}
else return {};
}
}
return res;
}
};
带佬的代码
比较好的做法是,队列维护2倍的序列,每一次加从小的数开始加,每一次删除从小的数开始删,因此符合先进先出数据结构,如果最后没有删完,说明不符合要求
class Solution {
public:
vector<int> findOriginalArray(vector<int>& a) {
sort(a.begin(), a.end());
vector<int> ret;
list<int> q;
for (int x : a) {
if (!q.empty() && x == q.front()) {
q.pop_front();
} else {
ret.push_back(x);
q.push_back(x * 2);
}
}
if (q.size() != 0) {
return {};
}
return ret;
}
};
5861. 出租车的最大盈利
比赛时的代码
又想复杂了,开了一个结构体进行排序,有点麻烦,
class Solution {
public:
typedef long long LL;
struct Passengers
{
int l, r, p;
bool operator < (const Passengers &t) const {
if (l != t.l) return l < t.l;
else if (r != t.r) return r < t.r;
return p < t.p;
}
};
long long maxTaxiEarnings(int n, vector<vector<int>>& rides) {
vector<LL> f(n + 1);
vector<Passengers> pa;
for (int i = 0; i < rides.size(); i ++ ) {
int l = rides[i][0], r = rides[i][1], p = rides[i][2];
pa.push_back({l, r, p});
}
sort(pa.begin(), pa.end());
int m = pa.size();
for (int i = 1, j = 0; i <= n; i ++ ) {
f[i] = max(f[i], f[i - 1]);
while (j < m && pa[j].l == i) {
int r = pa[j].r;
f[r] = max(f[r], f[pa[j].l] + r - pa[j].l + pa[j].p);
j ++ ;
}
}
return f[n];
}
};
带佬的代码
pair存邻接表和受益,每一次更新从起点到终点受益最大值
using ll = long long;
class Solution
{
public:
ll maxTaxiEarnings(int n, vector<vector<int>>& rides)
{
// g存储的是起点还有受益
vector<vector<pair<int, int>>> g(n);
for (auto r : rides) {
int a = r[0] - 1;
int b = r[1] - 1;
g[b].push_back({a, b - a + r[2]});
}
vector<ll> f(n);
for (int i = 1; i < n; ++i) {
f[i] = max(f[i], f[i - 1]);
for (auto r : g[i]) {
f[i] = max(f[i], f[r.first] + r.second);
}
}
return f[n - 1];
}
};
Leetcode5862. 使数组连续的最少操作数
最后一题忘记unique
了,小尴尬
class Solution {
public:
int minOperations(vector<int>& a) {
sort(a.begin(), a.end());
int m = a.size();
a.resize(unique(a.begin(), a.end()) - a.begin());
int n = a.size();
int r = 0, j = 0;
for (int i = 0; i < n; i ++ ) {
while (j < n && a[j] - a[i] < m) {
r = max(r, j - i);
j ++ ;
}
}
return m - r - 1;
}
};