LeetCode周赛第315&317场记录
第315场周赛值得学习的点不是很多,这里只是简单地总结一下。
前三题都非常简单,两道middle题都是关于数字反转的,使用标准库函数首先将其转为字符串,翻转过来之后再stoi返回即可高效地完,核心代码如下,其余的部分都是暴力法即可:
int reverseNumber(int Num)
{
string S = to_string(Num);
reverse(S.begin(), S.end());
return stoi(S);
}
第316场周赛因为要开组会,没有打。
接下来是317场周赛的部分:
6220. 可被三整除的偶数的平均值
第一题很简单,但是要注意的地方在于我们要求平均数的数字必须满足以下两个条件: 1.可以被3整除 2.必须是偶数
另外要注意,如果没有这样的数字,那么计数值为0,但不可以除以0。
完整的代码如下:
class Solution {
public:
int averageValue(vector<int>& nums)
{
int Sum = 0, Counter = 0;
for(auto Each : nums)
if((Each % 3 == 0) && (Each % 2 == 0))
{
Sum += Each;
++Counter;
}
return Counter == 0 ? 0 : (Sum / Counter);
}
};
6221. 最流行的视频创作者
第二题主要考查阅读理解能力对数据进行处理和排序,思路上没有什么难度,稍微有点费代码,直接给出含有注释的代码:
class Solution {
public:
vector<vector<string>> mostPopularCreator(vector<string>& creators, vector<string>& ids, vector<int>& views) {
int n = creators.size(), MaxViews = 0;
vector<vector<string>> Ans;
vector<string> TopCreators;
unordered_map<string, long long> ViewCounter;
unordered_map<string, pair<string, int>> TopVideos;
for(int i = 0 ; i < n ; ++i)
{
ViewCounter[creators[i]] += views[i];
if(TopVideos.count(creators[i]) == 0)
TopVideos[creators[i]] = make_pair(ids[i], views[i]);
else if(TopVideos[creators[i]].second < views[i])
TopVideos[creators[i]] = make_pair(ids[i], views[i]);
else if(TopVideos[creators[i]].second == views[i] && TopVideos[creators[i]].first > ids[i])
TopVideos[creators[i]] = make_pair(ids[i], views[i]);
else continue;
}
for(auto iter = ViewCounter.begin() ; iter != ViewCounter.end() ; ++iter)
{
if(iter->second > MaxViews)
{
TopCreators.clear();
TopCreators.push_back(iter->first);
MaxViews = iter->second;
}
else if(iter->second == MaxViews)
TopCreators.push_back(iter->first);
}
for(auto& Each : TopCreators)
Ans.push_back({Each, TopVideos[Each].first});
return Ans;
}
};
6222. 美丽整数的最小增量
这道题我一开始使用的是暴力法,但是这样一定会超时,因为这道题最终的答案可能会很大,超过
1
0
8
10^8
108。所以这道题使用暴力法从0开始一点点试下去一定会超时,这是一个基本的分析。
这道题还是应该使用模拟+贪心来解决,贪心的思路在比赛时我也想到了,但是我当时不知道该怎么处理进位,其实只需要对原先的数字+1就可以了,这在以下的代码中会集中展示。
class Solution {
int getBitSum(long long x)
{
int Ans = 0;
while(x)
{
Ans += (x % 10);
x /= 10;
}
return Ans;
}
public:
long long makeIntegerBeautiful(long long n, int target) {
long long Ans = 0, Base = 1;
while(getBitSum(n) > target)
{
Ans += (10 - (n % 10)) * Base;
n /= 10;
n++;
Base *= 10;
}
return Ans;
}
};
这道题总的代码量不大,但思路其实还是很巧妙的。
6223. 移除子树后的二叉树高度
这道题还是挺难的,需要两趟DFS,第一趟DFS是为了求每个子树的高度,并且记录在哈希表里。第二趟DFS就是为了求出删去每个子树时剩余部分的最大高度,结果也记录在一张哈希表里,随后就是直接回答查询即可。
这里直接给出灵茶山艾府的代码,作为记录:
lass Solution {
public:
vector<int> treeQueries(TreeNode *root, vector<int> &queries) {
unordered_map<TreeNode*, int> height;
function<int(TreeNode*)> get_height = [&](TreeNode *node) -> int {
return node ? height[node] = 1 + max(get_height(node->left), get_height(node->right)) : 0;
};
get_height(root);
int res[height.size() + 1];
function<void(TreeNode*, int, int)> dfs = [&](TreeNode *node, int depth, int rest_h) {
if (node == nullptr) return;
++depth;
res[node->val] = rest_h;
dfs(node->left, depth, max(rest_h, depth + height[node->right]));
dfs(node->right, depth, max(rest_h, depth + height[node->left]));
};
dfs(root, -1, 0);
for (auto &q : queries) q = res[q];
return queries;
}
};
上面这段代码中最难想的地方在rest_h这个量,这个变量中记录的是裁剪掉当前节点为根的子树之后,剩余二叉树的深度。之所以要引入这个变量,是因为在向更深的子树前进时需要考虑到之前的情况,看如下这样的一种情况:
注意在求裁剪掉6号节点之后二叉树的高度时,它应该同时考虑到之前1-3-2构成的子树,但是这个子树的高度只有4号节点知道,在4号节点向更深的节点出发时,应该将之前子树的结果传递6号节点。6号节点在1-3-2和1-4-5-7构成的子树中找到更大值,这才是6号节点的结果值。
|