当前位置: 首页 > news >正文

顺的网站建设策划网站快速优化排名官网

顺的网站建设策划,网站快速优化排名官网,未来最吃香的十大行业,嵌入式系统开发题目列表 3184. 构成整天的下标对数目 I 3185. 构成整天的下标对数目 II 3186. 施咒的最大总伤害 3187. 数组中的峰值 一、构成整天的下标对数目 I & II 可以直接二重for循环暴力遍历出所有的下标对,然后统计符合条件的下标对数目返回。代码如下 class So…

题目列表

3184. 构成整天的下标对数目 I

3185. 构成整天的下标对数目 II

3186. 施咒的最大总伤害

3187. 数组中的峰值

一、构成整天的下标对数目 I & II

可以直接二重for循环暴力遍历出所有的下标对,然后统计符合条件的下标对数目返回。代码如下

class Solution {
public:int countCompleteDayPairs(vector<int>& hours) {int n = hours.size(), ans = 0;for(int i = 0; i < n; i++) {for(int j = 0; j < i; j++){if((hours[i]+hours[j])%24==0)ans++;}}return ans;}
};

能不能优化呢?或者说能否去掉一层循环,用一次遍历计算出答案?

我们来思考一下内层循环的作用是什么,就是看前面的数字能否和当前数字能否组成能被24整除的数,也就是说只要我们在遍历的同时,统计满足加起来能被24的整除的数的出现次数,就能在O(1)的时间内得到与当前数字匹配的数字个数,从而降低时间复杂度。

如何得知两个数加起来能被24整除?只要知道它们的%24的值即可,比如一个数%24=20,那么我们只要找%24=4的数字即可,故代码如下

class Solution {
public:int countCompleteDayPairs(vector<int>& hours) {int cnt[24]{};int ans = 0;for(auto x:hours) {ans += cnt[(24-x%24)%24]; // (24-x%24)%24 用来计算另一个数%24的余数,为了防止出现24-0 = 24 的情况,故需要(...)%24cnt[x%24]++;}return ans;}
};

二、施咒的最大总伤害

先将数组排序,这样我们从前往后选咒语只要考虑当前咒语伤害是否大于前一个选择的咒语+2即可,当然咒语伤害相同可以同时被选中,所以我们还可以统计伤害相同的咒语的出现次数,然后将数组去重。最终,我们只要考虑当前咒语伤害是否大于前一个选择的咒语+2即可。

状态定义:f[i]表示前i个咒语中能得到的最大伤害

状态转移方程:

  • 选当前咒语,f[i] = f[j] + cnt[x]*x,x = power[i],f[j]为满足power[j] + 2 < power[i]的最接近当前位置的值
  • 不选当前咒语,f[i] = f[i-1]

故 f[i] = max( f[i-1],f[j] + cnt[x]*x),在遍历 j 的时候,我们不用每次都从头开始,j 只会变大,有点类似滑动窗口

代码如下

class Solution {using LL = long long;
public:long long maximumTotalDamage(vector<int>& power) {// 统计相同的咒语的出现次数unordered_map<int,int> mp;for(auto x:power) mp[x]++;// 排序 + 去重sort(power.begin(),power.end());power.erase(unique(power.begin(),power.end()),power.end());int n = power.size();LL ans = 0, j = 0;// f[i] 表示前i个咒语中的施咒最大总伤害// f[i] = max(f[i-1],f[j] + mp[x]*x)  x = power[i]vector<LL> f(n+1); for(int i = 0; i < n; i++) {while(power[j] + 2 < power[i])j++;f[i+1] = max(f[i], f[j] + (LL)mp[power[i]]*power[i]);ans = max(f[i+1], ans);}return ans;}
};

三、数组中的峰值

这题一看题目要求,单点修改 + 区间查询,可以用树状数组,也可以用线段树,代码如下

// 树状数组
struct BIT
{vector<int> t;BIT(int n):t(n+1){}void update(int i, int val){while(i < t.size()) {t[i] += val;i += (i&-i);}}int pre_sum(int i) {int res = 0;while(i > 0) {res += t[i];i -= (i&-i);}return res;}int query(int l, int r){if(l > r) return 0;return pre_sum(r) - pre_sum(l);}
};
class Solution {
public:vector<int> countOfPeaks(vector<int>& nums, vector<vector<int>>& q) {int n = nums.size();BIT t(n);auto update = [&](int i, int val) {if(nums[i] > nums[i-1] && nums[i] > nums[i+1])t.update(i+1,val);};for(int i = 1; i < n-1; i++) {update(i,1);}vector<int> ans;for(auto v:q) {if(v[0]==1) { // 区间查询ans.push_back(t.query(v[1]+1,v[2])); // 注意查询的区间,由于查询的子数组的左右端点不能算作峰值,并且树状数组的下标是从1开始的,并且使用前缀和相减得到区间内的峰值}else{ // 单点修改int x = v[1];// 先将可能会发生改变的点复原for(int i = max(x-1,1); i <= min(x+1,n-2); i++) {update(i,-1);}nums[x] = v[2];// 再重新更新可能会发生变化的点for(int i = max(x-1,1); i <= min(x+1,n-2); i++) {update(i,1);}}}return ans;}
};// 线段树
struct SegTree
{vector<int> t;SegTree(int n): t(n<<2){}void up(int o) {t[o] = t[o*2+1] + t[o*2+2];}void build(const vector<int>&a,int o,int l,int r) {if(l == r) {t[o] = 1;return;}int mid = (l + r) >> 1;build(a, o*2+1, l, mid);build(a, o*2+2, mid+1, r);up(o);}void update(int o,int l, int r, int i, int val) {if(l==r){t[o] = val;return;}int mid = (l + r) >> 1;if(i <= mid) update(o*2+1, l, mid, i, val);else update(o*2+2, mid+1, r, i, val);up(o);}int query(int o, int l, int r, int ql, int qr) {if(ql > qr) return 0;if(ql <= l && r <= qr)return t[o];int res = 0;int mid = (l + r) >> 1;if(mid >= ql) res += query(o*2+1, l, mid, ql, qr);if(mid < qr) res += query(o*2+2, mid+1, r, ql, qr);return res;}
};
class Solution {
public:vector<int> countOfPeaks(vector<int>& nums, vector<vector<int>>& q) {int n = nums.size();SegTree st(n);auto update = [&](int i, int val) {if(nums[i] > nums[i-1] && nums[i] > nums[i+1]) {st.update(0,0,n-1,i,val);}};for(int i = 1; i < n-1; i++) {update(i,1);}vector<int> ans;for(auto v:q) {if(v[0]==1) { // 区间查询ans.push_back(st.query(0,0,n-1,v[1]+1,v[2]-1));}else{ // 单点修改int x = v[1];for(int i = max(x-1,1); i <= min(x+1,n-2); i++) {update(i,0);}nums[x] = v[2];for(int i = max(x-1,1); i <= min(x+1,n-2); i++) {update(i,1);}}}return ans;}
};
http://www.yayakq.cn/news/849235/

相关文章:

  • 网站如何做流量前端开发培训得多少钱
  • 服务器外面打不开网站注册完域名之后怎么找到网站
  • 庆阳网站设计与建设芯片设计公司排名
  • 怎么做seo网站推广触屏手机网站模板
  • 汉川建设局网站中文网页开发工具
  • 石家庄信息网官方网站专业网站设计工作室
  • 手机qq钓鱼网站怎么做小米网站设计
  • 郑州网站建设yipinpai什么是网络营销的最大优点
  • 网站如何做才会有流量在线页游
  • 老师教学生做网站吗大连做网站团队
  • 襄阳做网站 优帮云wordpress主题有广告
  • 什么企业适合做网站深圳外包网站公司
  • 企业网站建设绪论提供定制型网站建设
  • 移动网站建设初学视频教程网站设计专家
  • 北京高端网站建设公司浩森宇特企业网站建设中有哪几个重要点
  • 电子商务网站名称和网址有引导页的网站
  • 深圳app开发公司怎么判断网站优化过度
  • 如何搭建视频网站做网站哪些软件
  • 北京建设集团网站微信发布wordpress
  • 怎么样才能建立网站平台丰都网站建设联系电话
  • 网站开发吧wordpress 初始密码
  • 东莞网站建设曼哈顿新科广西中小企业网站建设
  • 移动互联网站建设网页链接下载
  • ps海报制作教程步骤的网站免费海报在线制作网站
  • 株洲制作网站微信后台网站开发知识体系
  • 新乡网站优化广州黄埔区做网站培训机构
  • 重型机械网站开发模版设计本家居
  • 电影网站app怎么做的知名网站设计欣赏
  • 网站运营阶段江西省上饶市网站建设公司
  • 企业域名申请流程北京seo分析