• Leetcode---114双周赛


    题目列表

    2869. 收集元素的最少操作次数

    2870. 使数组为空的最少操作次数

    2871. 将数组分割成最多数目的子数组

    2872. 可以被 K 整除连通块的最大数目

    一、收集元素的最小操作次数

    直接模拟,倒序遍历即可,代码如下

    1. class Solution {
    2. public:
    3. int minOperations(vector<int>& nums, int k) {
    4. set<int>cnt;
    5. int n=nums.size();
    6. for(int i=n-1;i>=0;i--){
    7. if(nums[i]<=k) cnt.insert(nums[i]);
    8. if(cnt.size()==k) return n-i;
    9. }
    10. return n;
    11. }
    12. };
    13. //由于数据范围比较小,这里可以用位运算将空间复杂度将为O(1)
    14. class Solution {
    15. public:
    16. int minOperations(vector<int>& nums, int k) {
    17. long long s=(1LL<<(k+1))-1-1;//每个二进制位,0代表没有出现,1代表出现
    18. long long x=0;
    19. int n=nums.size();
    20. for(int i=n-1;i>=0;i--){
    21. if(nums[i]<=k) x|=(1LL<
    22. if(x==s) return n-i;
    23. }
    24. return n;
    25. }
    26. };

     二、使数组为空的最小操作次数

    这题只要发现规律也不是很难,根据题目意思我们需要统计每个数出现的次数,然后得到每个元素被删除的最小操作次数,相加得到答案,难点在于获取每种元素被删除的最小操作次数。

    其实这题的本质就是看一个数可以由多少个2和多少个3组成,并且2的个数加3的个数要最少,如果你数学好,这题就已经被秒了,如果你数学不好,那咋们就来举几个例子,找找规律

     代码如下

    1. class Solution {
    2. public:
    3. int minOperations(vector<int>& nums) {
    4. int ans=0;
    5. unordered_map<int,int>cnt;
    6. for(int x:nums)
    7. cnt[x]++;
    8. for(auto&[_,c]:cnt){
    9. if(c==1) return -1;
    10. ans+=(c+2)/3;
    11. }
    12. return ans;
    13. }
    14. };

     三、将数组分割成最多数目的子数组

    这题主要是了解按位与的性质---只有同为1,按位与后才是1,所以按位与的数字越多只会让数变得越来越小,这题要求子数组按位与之和要尽可能的小, 根据性质,所有数字按位与后的值才是最小的(设为a),如果将数组拆分成n个子数组,每个子数组按位与后的结果为bi(2<=i<=n),且bi>=a,所以sum(bi)>a,所以答案返回1,对吗?

    别忘了一种特殊情况,如果a=bi=0呢?这时我们就能对数组进行拆分了,根据贪心,每当我们遇到一段区间的按位与和为0,我们就将子数组个数+1,最后返回答案

    代码如下

    1. class Solution {
    2. public:
    3. int maxSubarrays(vector<int>& nums) {
    4. int ans=0;
    5. int s=-1;//-1的二进制位为全1,不会对按位与运算产生任何影响
    6. for(int i=0;isize();i++){
    7. s&=nums[i];
    8. if(s==0){
    9. ans++;
    10. s=-1;
    11. }
    12. }
    13. return max(ans,1);
    14. }
    15. };

    四、可以被k整除的连通块的最大数目

    这题找能否被k整除的连通块的个数,我们先计算每个连通块的值,只要连通块的值能被k整除,答案就+1(因为k的倍数减去k的倍数的结果还是k的倍数),代码如下

    1. class Solution {
    2. public:
    3. typedef long long LL;
    4. int maxKDivisibleComponents(int n, vectorint>>& edges, vector<int>& values, int k) {
    5. vectorint>>g(n);
    6. for(auto&e:edges){
    7. int x=e[0],y=e[1];
    8. g[x].push_back(y);
    9. g[y].push_back(x);
    10. }
    11. //计算以每一个结点为根的连通块的值
    12. int ans=0;
    13. functionint,int)>dfs=[&](int x,int fa)->LL{
    14. LL v=values[x];
    15. for(auto& y:g[x]){
    16. if(y!=fa){
    17. v+=dfs(y,x);
    18. }
    19. }
    20. if(v%k==0) ans++;
    21. return v;
    22. };
    23. dfs(0,-1);
    24. return ans;
    25. }
    26. };
  • 相关阅读:
    斗罗二:雨浩被言老抛弃,强行开除,首秀十万年魂环,戴华斌下跪
    MySQL数据库期末考试试题及参考答案(02)
    一周学会Django5 Python Web开发-Django5 ORM执行SQL语句
    关于Allegro17.4 3d模型大小不匹配问题解决
    k8s 读书笔记 - 深入掌握 Pod
    ES Aggs count distinct group by聚合排序查询
    react简单的服务器渲染示例(含redux, redux-thunk的使用)
    蓝桥杯刷题(一)
    金仓数据库KingbaseES客户端编程接口指南-ado.net(3. KingbaseES 驱动在 .NET 平台的配置)
    【NODE.JS】多进程架构(二)—— 句柄传递
  • 原文地址:https://blog.csdn.net/V_zjs/article/details/133553302