本文同步发表于 个人博客。
前言
感觉 l e e t c o d e leetcode leetcode 周赛不花时间,做一做还能保持一下手感,最重要的是能让人在周末早起。于是以后可能就会多打打 l e e t c o d e leetcode leetcode 了。
周赛273
AK时间: 21min
最终排名:
A 5963.反转两次的数字
给出数字 n n n, R ( n ) R(n) R(n) 表示 n n n 翻转后去掉前导零的结果,要求判断 R ( R ( n ) ) R(R(n)) R(R(n)) 是否等于 n n n。
0 ≤ n ≤ 1 0 6 0\le n\le 10^6 0≤n≤106。
做法
判断 n n n 是否有后导 0 0 0,即 n n n 是否是 10 10 10 的倍数即可,特判 n = 0 n=0 n=0 的情况。
代码
class Solution {
public:
bool isSameAfterReversals(int num) {
return (num == 0 || num % 10 != 0);
}
};
B 5964. 执行所有后缀指令
模拟题
做法
模拟即可
代码
class Solution {
public:
vector<int> executeInstructions(int n, vector<int>& startPos, string s) {
int m = s.size();
vector<int> ans(m);
for(int i = 0; i < m; i++){
int ok = 0;
int x = startPos[0], y = startPos[1];
for(int j = i; j < m; j++){
if(s[j] == 'L') y--;
if(s[j] == 'R') y++;
if(s[j] == 'U') x--;
if(s[j] == 'D') x++;
if(x < 0 || x >= n || y < 0 || y >= n) break;
ok++;
}
ans[i] = ok;
}
return ans;
}
};
C 5965.相同元素的间隔之和
给出 n n n 个数,对于每个 k ∈ [ 0 , n ) k\in[0,n) k∈[0,n),求出 ∑ i = 0 n − 1 ∣ i − k ∣ × [ a i = = a k ] \sum\limits_{i=0}^{n-1}|i-k|\times[a_i==a_k] i=0∑n−1∣i−k∣×[ai==ak]。
1 ≤ n ≤ 1 0 5 , 1 ≤ a i ≤ 1 0 5 1\le n\le 10^5, 1\le a_i\le 10^5 1≤n≤105,1≤ai≤105。
做法
很套路的题,把
a
i
a_i
ai 相同的放到一个数组里,然后求一下前缀和,把绝对值拆开计算即可。
复杂度为
O
(
n
)
O(n)
O(n) 或者
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)。
代码
typedef long long ll;
class Solution {
public:
vector<long long> getDistances(vector<int>& arr) {
map<int, vector<int>> mp;
int n = arr.size();
vector<ll> ans(n);
for(int i = 0; i < n; i++) mp[arr[i]].push_back(i);
for(auto& e: mp){
auto& v = e.second;
int n = v.size();
vector<ll> s(n);
for(int i = 0; i < n; i++){
if(i > 0) s[i] = s[i - 1];
s[i] += v[i];
}
auto cal = [&](int l, int r){
if(l > r) return 0ll;
ll a = s[r], b = (l > 0? s[l - 1]: 0);
return a - b;
};
for(int i = 0; i < n; i++){
ll t1 = i + 1, t2 = n - i;
ll s1 = t1 * v[i] - cal(0, i), s2 = cal(i, n - 1) - t2 * v[i];
ans[v[i]] = s1 + s2;
}
}
return ans;
}
};
D 5966. 还原原数组
给出 2 n 2n 2n 个数,问能否划分成 n n n 对 ( b i , c i ) (b_i,c_i) (bi,ci),满足 c i > b i , c i − b i c_i>b_i,c_i-b_i ci>bi,ci−bi 都相等,并且 c i ≡ b i ( m o d 2 ) c_i\equiv b_i(\mod 2) ci≡bi(mod2),返回 b i + c i 2 \frac{b_i+c_i}{2} 2bi+ci。保证有解。
1 ≤ n ≤ 1000 1\le n\le 1000 1≤n≤1000。
做法
九折还 h a r d hard hard…
枚举
c
i
−
b
i
c_i-b_i
ci−bi 的值,然后从小到大枚举
b
i
b_i
bi,用一个
s
e
t
set
set 或者
m
u
l
t
i
s
e
t
multiset
multiset 或者
m
a
p
map
map 来快速判断有没有匹配的
c
i
c_i
ci。
总的复杂度是
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)。
代码
class Solution {
public:
vector<int> recoverArray(vector<int>& nums) {
sort(nums.begin(), nums.end());
int n = nums.size();
for(int i = 1; i < n; i++){
vector<int> vis(n);
int k = nums[i] - nums[0];
if(k == 0 || k % 2) continue;
set<pair<int, int>> s;
for(int j = 0; j < n; j++) s.insert({nums[j], j});
vector<int> a;
vis[0] = vis[i] = 1;
a.push_back((nums[i] + nums[0]) / 2);
s.erase({nums[0], 0}), s.erase({nums[i], i});
int ok = 1;
for(int j = 1; j < n; j++){
if(vis[j]) continue;
int v = nums[j] + k;
auto it = s.lower_bound({v, 0});
if(it == s.end() || it->first != v){
ok = 0;
break;
}
a.push_back((nums[j] + v) / 2);
vis[j] = vis[it->second] = 1;
s.erase({nums[j], j}), s.erase({it->first, it->second});
}
if(ok){
return a;
break;
}
}
return {};
}
};