LeetCode第 285 场周赛题解
6027. 统计数组中峰和谷的数量
题目描述:给你一个数组nums
,统计山峰和山谷的数量,山峰山谷的定义见题目
思路:数据范围不大,根据题意暴力模拟即可,若数据范围很大,则将相邻且相等的元素删除其一,对于删除后的数组,可以\(O(n)\)求解
时间复杂度:\(O(n^2)\)
参考代码:
class Solution {
public:
int countHillValley(vector<int>& nums) {
int res = 0, n = nums.size();
vector<int>vis(n + 1 , false);
for(int i = 1 ; i < n - 1 ; ++i){
int lr = -1;
for(int j = i - 1 ; j >= 0 ;--j){
if(nums[j] == nums[i]) continue;
lr = nums[j];
break;
}
if(lr == -1) continue;
int rs = -1;
for(int j = i + 1 ; j < n ; ++j){
if(nums[j] == nums[i]) continue;
rs = nums[j];
break;
}
if(rs == -1) continue;
if(lr > nums[i] && rs > nums[i]){
++res;
vis[i] = true;
if(vis[i - 1] == true && nums[i - 1] == nums[i]) --res;
}
else if(lr < nums[i] && rs < nums[i]){
++res;
vis[i] = true;
if(vis[i - 1] == true && nums[i - 1] == nums[i]) --res;
}
}
return res;
}
};
\(O(n)\)解法:
class Solution {
public:
int countHillValley(vector<int>& nums) {
deque<int>q;
for(auto& num : nums){
if(q.empty())q.push_back(num);
else if(q.back() == num) continue;
else q.push_back(num);
}
nums.clear();
while(!q.empty()){
nums.push_back(q.front());
q.pop_front();
}
int res = 0 , n = nums.size();
for(int i = 1 ; i < n - 1 ; ++i){
if(nums[i] < nums[i - 1] && nums[i] < nums[i + 1]) ++res;
if(nums[i] > nums[i - 1] && nums[i] > nums[i + 1]) ++res;
}
return res;
}
};
6028. 统计道路上的碰撞次数
题目描述:给你一个长度为\(n\)的字符串s
表示n
辆车的状态,R
表示向右行驶,L
表示向左行驶,S
表示不动。若两辆相对行驶的车相撞积两分,若一个行驶的车撞上了一个静止的车积一分,两辆车相撞之后就会保持静止。问最终积分是多少。
思路:根据题意模拟即可
时间复杂度:\(O(n)\)
参考代码:
class Solution {
public:
int countCollisions(string s) {
int res = 0;
int cntlr = 0 , cntrs = 0, stop = 0;
for(auto& c : s){
if(c == 'S'){
res += cntrs;
cntrs = 0;
stop = 1;
}
else if(c == 'L'){
if(cntrs){
res += cntrs + 1;
cntrs = 0;
stop = 1;
}
else if(stop) res++;
}
else ++cntrs;
}
return res;
}
};
6029. 射箭比赛中的最大得分
题目描述:两个人比赛射箭,假定这两个人用A
和B
表示,他们都射n
支箭,靶总共有12
个区域,分别表示0 , 1 , ... , 11
分,对于同一分数区域,只有当B
射在该区域的箭的数量多于A
射在该区域的箭的数量时,B
才可以获得该区域所代表的分数,问B
最多能获得多少分。
思路:考虑到总共只有12
个区域,所以我们枚举B
胜利的区域,然后检验所用箭的数量是否超过阈值即可。注意B
使用的箭的总数量与A
使用的箭的总数量必须相等。
时间复杂度:\(O(12 * 2 ^{12})\)
参考代码:
class Solution {
public:
vector<int> maximumBobPoints(int numArrows, vector<int>& a) {
vector<bool>vis(12 , 0);
vector<int>res;
int mx = 0;
auto dfs = [&](auto&& dfs , int cur)->void{
if(cur == 12){
int cnt = 0, sum = 0;
vector<int>ans(12 , 0);
for(int i = 0 ; i < 12 ; ++i){
if(vis[i] == false) continue;
ans[i] = a[i] + 1;
cnt += a[i] + 1;
sum += i;
}
if(cnt > numArrows) return ;
if(sum <= mx) return ;
ans[0] += numArrows - cnt;
mx = sum;
res = ans;
return ;
}
dfs(dfs , cur + 1);
vis[cur] = true;
dfs(dfs , cur + 1);
vis[cur] = false;
};
dfs(dfs , 0);
return res;
}
};
6030. 由单个字符重复的最长子字符串
题目描述:给你一个长度为n
的字符串s
,在给你q
个询问,每次询问修改某处字符为给定字符,问每次修改后字符串s
中由单个字符重复组成的最长子子符串的长度。
思路:比较明显可以使用线段树,维护最长子符串。同时维护区间的前缀最长,后缀最长,区间最长,最前面的数的值,最后面的数的值这5
个信息,然后单点修改即可,每次询问的答案就是tree[1].mx
。
时间复杂度:\(O(nlogn + qlogn)\)
参考代码:
class Solution {
private:
struct SegTree {
int lr, rs, mid;
int val, pre, nxt, mx, preval, nxtval;
};
vector<SegTree> tree;
void pushUp(int rt) {
tree[rt].mx = max(tree[rt << 1].mx, tree[rt << 1 | 1].mx);
if (tree[rt << 1].nxtval == tree[rt << 1 | 1].preval) {
int len = tree[rt << 1].nxt + tree[rt << 1 | 1].pre;
tree[rt].mx = max(tree[rt].mx, len);
}
tree[rt].pre = tree[rt << 1].pre;
tree[rt].nxt = tree[rt << 1 | 1].nxt;
tree[rt].preval = tree[rt << 1].preval;
tree[rt].nxtval = tree[rt << 1 | 1].nxtval;
if (tree[rt].pre == tree[rt << 1].rs - tree[rt << 1].lr + 1) {
if (tree[rt << 1].nxtval == tree[rt << 1 | 1].preval) tree[rt].pre += tree[rt << 1 | 1].pre;
else;
}
if (tree[rt].nxt == tree[rt << 1 | 1].rs - tree[rt << 1 | 1].lr + 1) {
if (tree[rt << 1].nxtval == tree[rt << 1 | 1].preval) tree[rt].nxt += tree[rt << 1].nxt;
else;
}
return;
}
void buildTree(string& s, int rt, int lr, int rs) {
tree[rt].lr = lr; tree[rt].rs = rs; tree[rt].mx = 0;
if (lr == rs) {
tree[rt].val = s[lr - 1] - 'a' + 1;
tree[rt].mx = 1;
tree[rt].preval = tree[rt].nxtval = tree[rt].val;
tree[rt].pre = tree[rt].nxt = 1;
return;
}
int mid = tree[rt].mid = lr + rs >> 1;
buildTree(s, rt << 1, lr, mid);
buildTree(s, rt << 1 | 1, mid + 1, rs);
pushUp(rt);
return;
}
void update(int rt, int pos , int val) {
if (tree[rt].lr > pos || tree[rt].rs < pos) return;
if (tree[rt].lr == tree[rt].rs) {
tree[rt].val = val;
tree[rt].preval = val;
tree[rt].nxtval = val;
return;
}
if (tree[rt].mid >= pos) update(rt << 1, pos, val);
else update(rt << 1 | 1, pos, val);
pushUp(rt);
return;
}
public:
vector<int> longestRepeating(string s, string queryCharacters, vector<int>& queryIndices) {
int n = s.size();
tree = vector<SegTree>(n + 5 << 2);
buildTree(s, 1, 1, n);
int m = queryCharacters.size();
vector<int>res(m , 0);
for (int i = 0; i < m; ++i) {
int pos = queryIndices[i] + 1, val = queryCharacters[i] - 'a' + 1;
update(1, pos, val);
res[i] = tree[1].mx;
}
return res;
}
};
作者:cherish.
出处:https://home.cnblogs.com/u/cherish-/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。