LeetCode---120双周赛

题目列表

2970. 统计移除递增子数组的数目 I

2971. 找到最大周长的多边形

2972. 统计移除递增子数组的数目 II

2973. 树中每个节点放置的金币数目

一、统计移除递增子数组的数目I

这题的数据范围不高,可以直接暴力,后面的第三题和它一样,但是数据范围增强,这里先写一种暴力的解法,后面第三题在讲个O(n)的解法

class Solution {
public:int incremovableSubarrayCount(vector<int>& nums) {int n=nums.size();int ans=0;//枚举删除的子数组的左右断点[i,j]for(int i=0;i<n;i++){for(int j=i;j<n;j++){bool flag=true;vector<int>v(nums.begin(),nums.begin()+i);v.insert(v.end(),nums.begin()+j+1,nums.end());for(int k=0;k<v.size();k++){if(k&&v[k]<=v[k-1]){flag=false;break;}}ans+=flag;}}return ans;}
};

二、找到最大周长的多边形

这题的难度不高,题目意思说的很明确,我们只要照着模拟就行,用贪心的思想:因为多边形的周长要最长,我们肯定是先考虑全选的情况,然后看是否符合多边形的条件,如果不符合,我们只能将最长的边换小一点,同时比最长边小的边全部选上,这样不等式左边的数的和才会尽可能的大,会更有可能满足多边形的条件

代码如下

class Solution {
public:long long largestPerimeter(vector<int>& nums) {int n=nums.size();sort(nums.begin(),nums.end());long long sum=accumulate(nums.begin(),nums.end(),0LL);for(int i=n-1;i>1;i--){//多边形最少要三条边if(sum-nums[i]>nums[i])return sum;sum-=nums[i];}return -1;}
};

三、移除递增子数组的数目II

第一题的数据加强版,第一题我们是纯模拟,时间复杂度为O(n^3),很显然过不了,所以我们要观察它给的示例,来找找规律

上面只截取了示例1,是一个特殊情况,当数组本身就是递增的情况下,答案就是数组能产生多少个子数组,为(n+1)*n/2

那么如果数组不严格单调增呢?

我们可以将子数组分为三种:

1、右端点固定在数组最右边,看前缀的递增数组能到哪里

2、左端点固定在数组最左边,看后缀的递增数组能到哪里

3、子数组在数组的中间

前面两种情况很好解决,第三种情况怎么求?

首先我们要明确一点,由于我们是在中间找子数组,所以数组的前缀和后缀一定要是递增的,我们只要看前缀的最后一个数是否比后缀的第一个数大就行。

同时为了得到子数组的数量和降低时间复杂度,我们可以用双指针(同向双指针),这里用到前缀/后缀数组的单调性,可以简单说明一下该算法的步骤和正确性

设i为a数组的下标,j为b数组的下标,都从前往后移动,两个数组同时满足单调增

  • 如果a[i]<b[j],根据单调性,j后面的数字一定也满足小于关系,所以直接加上后面的数字个数,同时i++,看看a数组的下一个数字是否也小于b[j]
  • 如果a[i]>=b[j],根据单调性,j前面的数字也一定满足大于等于关系,所以直接让j++

总而言之,我们在遍历a数组的同时,让b数组中的数始终被划分为可能满足条件和永远不可能满足条件两个部分,时间复杂度的降低本质在于永远不能满足条件的部分不会被重复的遍历到

代码如下

class Solution {
public:long long incremovableSubarrayCount(vector<int>& nums) {int n=nums.size();//找前缀递增的最后一个元素下标int i=0;while(i<n-1){if(nums[i]>=nums[i+1])break;i++;}if(i==n-1) return 1LL*n*(n+1)/2;//找后缀递增的第一个元素下标int j=n-1;while(j>0){if(nums[j-1]>=nums[j])break;j--;}//要考虑将整个数组变成空数组的情况,所以单独+1long long ans=(n - j) + (i + 1) + 1;int l=0,r=j;while(l<=i&&r<n){if(nums[l]<nums[r]){ans+=(n-r);l++;}else{r++;}}return ans;}
};

(当然,双指针同时从后往前遍历也是可以的,这样可以将找递增后缀和双指针结合起来写,有兴趣的读者可以回去试着去改改代码) 

四、树中每个节点放置的金币数目

这题说实在的没有什么难点,关键是你要知道如何建图和遍历这棵树。

还有一个比较关键的点简单说明一下:当子树中的结点个数>=3时,我们如何选取3个数字使得它们的乘积最大?这其实很好思考,我们只要将数组排序,因为题目要求小于0,就放置0个金币,所以我们只要考虑选三个数字,它们的乘积为最大的正整数即可,

两种可能性:

  • 三个数都为正,选择最大的三个数
  • 三个数中两个数为负,选最小的两个数,一个数为正,选一个最大的数

至于这两种情况中是否会出现三个数全为负数的情况,我们根本不用管,因为题目要求小于0,就放置0个金币。

有人可能也是这样写的,但是超时了没过,这里讲一下为什么,因为数组太大了,排序需要时间,但其实我们没必要将子树的所有cost都排序,我们只想知道这些数字中最小的两个数和最大的三个数(当然要考虑到重合的情况,因为我们不能凭空多出数字)。

代码如下

class Solution {
public:vector<long long> placedCoins(vector<vector<int>>& edges, vector<int>& cost) {int n=cost.size();vector<long long>ans(n);vector<vector<int>>g(n);for(auto&e:edges){int x=e[0],y=e[1];g[x].push_back(y);            g[y].push_back(x);}function<vector<long long>(int,int)>dfs=[&](int x,int fa)->vector<long long>{vector<long long>v({cost[x]});for(int y:g[x]){if(y!=fa){vector<long long>w=dfs(y,x);v.insert(v.end(),w.begin(),w.end());}}int m=v.size();if(m<3)ans[x]=1;else{sort(v.begin(),v.end());long long a=v[m-1]*v[m-2]*v[m-3];long long b=v[0]*v[1]*v.back();ans[x]=max(max(a,b),0LL);}if(m>5){v.erase(v.begin()+2,v.end()-3);}return v;};dfs(0,-1);return ans;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/314222.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机械过滤器(石英砂过滤器)和多介质过滤器的区别 工作原理动画

​ 1&#xff1a;机械过滤器多介质石英砂过滤器介绍 机械过滤器&#xff1a;预处理水质的关键设备 机械过滤器&#xff0c;也被称为压力式过滤器&#xff0c;是纯水制备过程中不可或缺的预处理设备。它在水处理系统中扮演着重要的角色&#xff0c;能够有效地去除水中的悬浮物…

2024.1.1 hive_sql 题目练习,开窗,行列转换

重点知识: 在使用group by时&#xff0c;select之后的字段要么包含在聚合函数里&#xff0c;要么在group by 之后 进行行转列,行转列的核心就是使用concat_ws函数拼接(分隔符,内容), -- 以及collect_list函数进行收集,list不去重, set去重无序 列转行,核心就是使用炸裂函数把东…

SpringCloud-高级篇(十)

&#xff08;1&#xff09;单节点Redis问题 缓存大家都不陌生&#xff0c;在企业里面只要做缓存都会用到Redis&#xff0c;我们在使用的时候都是做的单节点部署&#xff0c;单节点部署是存在一些问题的&#xff0c;分布式缓存正是Redis的集群&#xff0c;正是为了解决单节点部署…

个人简历范本(精选5篇)

HR浏览一份简历也就25秒左右&#xff0c;如果你连「好简历」都没有&#xff0c;怎么能找到好工作呢&#xff1f; 如果你不懂得如何在简历上展示自己&#xff0c;或者觉得怎么改简历都不出彩&#xff0c;那请你一定仔细读完。 个人求职简历第 1 篇 男 22 本科 AI简历 市场营…

在线课程学习管理

### 起步1. 使用 IDEA 导入项目 2. 执行 sql 目录下的online_study_system.sql 文件 3. 修改 mysql.properties 中数据库连接信息 4. 运行程序| 用户名| 密码 | | ------------- |:-------------| | admin | 123 | | 李老师 | 123 | | 张老师 | 123 | | 刘老师 | 123 | | 曹老师…

国际物流公司科普_集装箱种类区分和介绍_箱讯科技

集装箱运输的不断发展&#xff0c;为适应装载不同种类货物的需要&#xff0c;因而出现了不同种类的集装箱。今天和大家一起来总结一下。 按使用材料分类 根据箱子主体部件&#xff08;侧壁、端壁、箱顶等&#xff09;采用什么材料&#xff0c;就叫做什么材料制造的集装箱&…

C++ 类和对象 (中)

默认成员函数&#xff1a; C环境下每一个类在定义是时编译器会自动生成六个成员函数&#xff08;在没有显示定义的情况下&#xff09;&#xff0c;分别是构造函数、析构函数、拷贝构造函数、赋值运算符重载、普通变量和const常量的取地址重载&#xff0c;它们大大弥补了原先C语…

【进阶KMP算法】nextval手算代码均有详解(每步配图)

这里是进阶&#xff0c;所以如果有小伙伴不知道KMP算法是什么的话&#xff0c;请看上一章&#xff08;写的很清楚&#xff09;&#xff0c;故我这里概念什么的就不再过多描述。 引入&#xff1a; 要改进那么肯定要知道&#xff0c;哪里有不足&#xff0c;我们假设目标串s为“…

c# 捕获全部线程的异常 试验

1.概要 捕获全部线程的异常 试验&#xff0c;最终结果task的异常没有找到捕获方法 2.代码 2.1.试验1 2.1.1 试验结果 2.2 代码 2.2.1主程序代码 using NLog; using System; using System.Threading; using System.Windows.Forms;namespace 异常监控 {static class Program…

C++继承与派生——(8)多继承

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 苦难和幸福一样&#xff0c;都是生命盛…

Java API 操作Docker浅谈

背景&#xff1a; 使用com.github.docker-java库可以很方便地在Java中操作Docker。下面是一个详细的教程&#xff0c;包括创建镜像、创建容器、启动容器、停止容器和删除容器的步骤以及每一步的说明。 前提&#xff1a; 首先&#xff0c;在你的Java项目中添加com.github.doc…

gRPC之内置Trace

1、内置Trace grpc内置了客户端和服务端的请求追踪&#xff0c;基于golang.org/x/net/trace包实现&#xff0c;默认是开启状态&#xff0c;可以查看事 件和请求日志&#xff0c;对于基本的请求状态查看调试也是很有帮助的&#xff0c;客户端与服务端基本一致&#xff0c;这里…