ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Leetcode周赛-244

2021-06-07 21:02:59  阅读:239  来源: 互联网

标签:周赛 箱子 int bt 244 vector ans com Leetcode


第一题:https://leetcode-cn.com/problems/determine-whether-matrix-can-be-obtained-by-rotation/

1886. 判断矩阵经轮转后是否一致

思路:90度顺时针旋转后,(i,j)->(j,n-i-1),分别计算旋转得到的四种情况进行判断即可。
反思:判断两个二维矩阵相等可以之间用vector<vector> a,b; 直接判断 a==b;
代码:

    vector<vector<int>> sol(vector<vector<int>> ans){
        int n=ans.size();
        vector<vector<int>> atm(n,vector<int>(n));
        \\以上两行可以改为 auto atm=ans;
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
            atm[j][n-i-1]=ans[i][j];
            return atm;
    }
    bool findRotation(vector<vector<int>>& a, vector<vector<int>>& b) {
        for(int i=0;i<4;i++){
            if(a==b)return true;
            a=sol(a);
        }
        return false;
    }

第二题:https://leetcode-cn.com/problems/reduction-operations-to-make-the-array-elements-equal/

1887. 使数组元素相等的减少操作次数

思路:每个数字都要变到最小值,而这个过程中的cost是这个数字到最小数字的距离(两个数字间从小到大不同数值的个数)
反思:不要忘记先排序。
代码:

class Solution {
public:
    int reductionOperations(vector<int>& s) {
        int ans=0,num=0;
        sort(s.begin(),s.end());
        for(int i=1;i<s.size();i++){
            if(s[i]!=s[i-1])num++;
            ans+=num;
        }
        return ans;
    }
};

第三题:https://leetcode-cn.com/problems/minimum-number-of-flips-to-make-the-binary-string-alternating/

1888. 使二进制字符串字符交替的最少反转次数

思路:
方法一:首先根据规律:字符交替的情况只有两种情况:奇数为0或者奇数为1,计算出一种情况下需要第二种变换的次数,然后遍历字符串,计算每一位作为开头,把此位前的移动到最后的情况下需要变换的次数,然后输出最小值即可。由于每种情况都是从上一种情况中转换过来的,所以只需要计算状态转换的影响即可。
规律:字符串两种情况所需要的变换次数关系为:a次和n-a次
代码:

class Solution {
public:
    int minFlips(string s) {
        int a=0,b=0;
        for(int i=0;i<s.size();i++){
          if(i%2&&(s[i]-'0')){
              //cout<<i<<endl;
              a++;
          }
          if((i%2==0)&&(s[i]=='0')){
             //cout<<i<<endl;
              a++;
          }
        }
        int len=s.size();
        int ans=min(a,len-a);
        a=len-a;
        for(int i=0;i<s.size();i++){
            if(s[i]-'0'){
                a--;
            }
            a=len-1-a;
            //cout<<a<<endl;
            if(s[i]=='0'&&len%2==0)a++;
            if(s[i]=='1'&&len%2==1)a++;
            ans=min(ans,len-a);
            ans=min(ans,a);
            //cout<<i<<" "<<a<<endl;
        }
        return ans;
    }
};
``
方法二:
前缀+后缀:对于偶数情况,操作一并不能改变某一位的奇偶性,当奇数的情况下,操作一可以使前段的奇偶变换,所以可以前段和后端分别求前缀和后枚举操作一结束的点即可。
代码:
```C++
class Solution {
public:
    int minFlips(string s) {
        const int m=s.size();
        int l[2][m],r[2][m];
        for(int i=0;i<2;i++)
            for(int j=0,num=0,k=i;j<m;j++,k^=1)
            {
                if((s[j]-'0')==k)num++;
                l[i][j]=num;
            }
        for(int i=0;i<2;i++)
            for(int j=m-1,num=0,k=i;j>=0;j--,k^=1){
                if((s[j]-'0')==k)num++;
                r[i][j]=num;
            }
        int ans= min(r[0][0],r[1][0]);
        if(m%2==0)return ans;
        for(int i=0;i<m-1;i++){
            ans=min(ans,l[0][i]+r[1][i+1]);
            ans=min(ans,l[1][i]+r[0][i+1]);
        }
        return ans;
    }
};

第四题:https://leetcode-cn.com/problems/minimum-space-wasted-from-packaging/

1889. 装包裹的最小浪费空间

思路:排序后二分判断
包裹数据范围是1e5,箱子数目总和数据范围是1e5,所以题目时间复杂度应该在O(NlogN)即可,我们可以对每个箱子供应商的包裹进行判断,箱子数总和为M(<1e5),对于i供应商的j箱子,j箱子能够装的包裹范围为[l,r),产生的浪费空间贡献:\(a[i][j]\times(l-r)-\sum_{k=l}^{r-1}{p[k]}\),此时时间复杂度为NNM,对于\(\sum_{k=l}^{r-1}{p[k]}\)可以通过前缀和优化为O(1),对于查找[l,r),可以用upper_bound二分查找优化到O(logN)所以对箱子判断的时间复杂度为O(MlogN),二分包裹前需要对包裹先排序,同样箱子判断前也需要对箱子排序,总时间复杂度为O(NlogN+MlogM+MlogN)
反思:
1.浪费空间的数据范围应该小于1e10,两种情况比较浪费空间时很明显不应该拿取模后的数值进行比较,可以long long 存储,最后返回时取模即可;
2.无法把所有包裹放入箱子的时候返回-1,则最后的结果初始值应该大于1e10,可以用LLONG_MAX进行初始化,而不是用0x3f3f3f3f(int类型不穷大,小于1e10);
代码:

class Solution {
public:
    int minWastedSpace(vector<int>& p, vector<vector<int>>& b) {
        int n=p.size(), m=b.size();
        const int mod=(int)1e9+7;
        vector<long long>qz(n+5);
        sort(p.begin(),p.end());
        for(int i=1;i<=n;i++){
            qz[i]=qz[i-1]+p[i-1];
        }
        long long ans=LLONG_MAX;
        for(int i=0;i<m;i++){
            vector<int> & bt=b[i];
            sort(bt.begin(),bt.end());
            if(bt[bt.size()-1]<p[n-1])continue;
            int s=0,t;
            long long num=0;
            for(int j=0;j<bt.size();j++){
                t=upper_bound(p.begin(),p.end(),bt[j])-p.begin();
                //cout<<s<<" "<<t<<endl;
                num=(num+1LL*(t-s)*bt[j]-(qz[t]-qz[s]));
                s=t;
                if(t==n)break;
            }
            //cout<<num<<endl;
            ans=min(ans,num);
        }
        return ans== LLONG_MAX ? -1:ans%mod;
    }
};

标签:周赛,箱子,int,bt,244,vector,ans,com,Leetcode
来源: https://www.cnblogs.com/abestxun/p/14859845.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有