LeetCode第 281 场周赛题解
第 281 场周赛 - 力扣
T1
题目描述:给你一个正整数 \(num\) ,请你统计并返回 小于或等于 \(num\) 且各位数字之和为 偶数 的正整数的数目。
数据范围:\(1 \leq num \leq 1000\)
思路:数据范围很小,暴力枚举即可。
时间复杂度:\(O(nlog_{10}n)\)
参考代码:
class Solution {
public:
int countEven(int num) {
int res = 0;
for(int i = 2 ; i <= num ; ++i){
int j = i , sum = 0;
while(j){
sum += j % 10;
j /= 10;
}
res += !(sum & 1);
}
return res;
}
};
T2
题目描述:给你一个链表的头节点 head
,该链表包含由 0
分隔开的一连串整数。链表的 开端 和 末尾 的节点都满足 Node.val == 0
。对于每两个相邻的 0
,请你将它们之间的所有节点合并成一个节点,其值是所有已合并节点的值之和。然后将所有 0
移除,修改后的链表不应该含有任何 0
。返回修改后链表的头节点 head
。
思路:根据题意模拟即可
时间复杂度:\(O(n)\)
参考代码:
class Solution {
public:
ListNode* mergeNodes(ListNode* head) {
vector<int> st;
ListNode* p = head;
while(p != nullptr){
int dx = p->val;
p = p->next;
if(dx == 0) st.push_back(dx);
else{
if(st.back() == 0) st.push_back(dx);
else st[st.size() - 1] += dx;
}
}
int n = st.size();
for(int i = 1 ; i < n ; i += 2){
if(i == 1) p = new ListNode(st[i] , nullptr);
else p->next = new ListNode(st[i] , nullptr), p = p->next;
if(i == 1) head = p;
}
return head;
}
};
T3
题目描述:使用给定的字符构造一个字典序最大的字符串,满足连续出现的相同字符的数量不超过阈值。
思路:根据题意,模拟加贪心即可
时间复杂度:\(O(n)\)
参考代码:
class Solution {
public:
string repeatLimitedString(string s, int rp) {
string res;
vector<int>cnt(26 , 0);
for(auto& c : s) cnt[c - 'a']++;
for(int i = 25 ; i >= 0 ; --i){
if(cnt[i] == 0) continue;
for(int j = 1 ; j <= min(rp , cnt[i]) ; ++j) res += (char)(i + 'a');
cnt[i] -= min(cnt[i] , rp);
if(cnt[i] == 0) continue;
int idx = -1;
for(int j = i - 1 ; j >= 0 ; --j){
if(cnt[j] == 0) continue;
idx = j;
break;
}
if(idx == -1) break;
--cnt[idx];
res += (char)(idx + 'a');
++i;
}
return res;
}
};
T4
题目描述:给你一个长度为\(n\)的数组\(nums\),和一个整数\(k\),求满足以下条件的数对个数:
- $ 1\leq i < j \leq n$
- \(nums_i * nums_j\;mod\;k\; = \;0\)
思路:根据题意容易知道\(gcd(nums_i , k) * gcd(nums_j , k)\;mod\;k\;=\;0\)。故我们可以先将\(gcd(nums_i , k) , 1 \leq i \leq n\)求出来,存储到桶中。然后考虑到\(gcd(nums_i , k)\)一定在\(k\)的因子中,所以我们枚举\(k\)的所有因子,若两个因子的乘积能被\(k\)整除,那么就将其对应数量相乘。注意到若\(nums_i * nums_i\;mod\;k\;=\;0\),那么会对答案有重复贡献,在预处理时应\(-1\),最终返回其统计值的一半即可。
时间复杂度:\(O(nlogn)\)
参考代码:
class Solution {
public:
long long coutPairs(vector<int>& nums, int k) {
long long res = 0;
vector<int>cnt(k + 1 , 0);
for(auto num : nums) {
if(1ll * num * num % k == 0)--res;
int gd = gcd(num , k);
++cnt[gd];
}
vector<int>a;
for(int i = 1 ; i * i <= k ; ++i){
if(k % i != 0) continue;
a.push_back(i);
if(i != k / i) a.push_back(k / i);
}
sort(a.begin() , a.end());
for(auto i : a){
for(auto j : a){
if(1ll * i * j % k == 0) res += 1ll * cnt[i] * cnt[j];
}
}
return res >> 1;
}
};
作者:cherish.
出处:https://home.cnblogs.com/u/cherish-/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。