Leetcode第 279 场周赛

Posted MangataTS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode第 279 场周赛相关的知识,希望对你有一定的参考价值。

比赛连接

https://leetcode-cn.com/contest/weekly-contest-279/

A.对奇偶下标分别排序(暴力)

难度

思路

我们直接开两个数组或者vector容器,然后将奇偶位置的数分别存放不同的容器中,然后排序归并即可

代码

class Solution 
public:
    vector<int> sortEvenOdd(vector<int>& nums) 
        vector<int> a,b,c;
        int n = nums.size();
        for(int i = 0;i < n; ++i) 
            if(i & 1) b.push_back(nums[i]);
            else a.push_back(nums[i]);
        
        sort(a.begin(),a.end());
        sort(b.begin(),b.end(),greater<int>());
        for(int i = 0,l = 0,r = 0;i < n; ++i) 
            if(i & 1) c.push_back(b[r++]);
            else c.push_back(a[l++]);
        
        return c;
    
;

B.重排数字的最小值(暴力)

难度

思路

我们需要对输入的num进行分类讨论

  • 如果是等于0的话,我们直接返回0就好了
  • 如果是大于0的话那么我们肯定是希望每一个位置上的数字小的在前面,但是这就可能让这个数字串变成了有前缀0的情况,这个时候我们只需要把第一个0和从左到右第一个不为0的位置的数进行交换就好了
  • 如果是小于0的话,那么我们肯定希望每一个位置上的数字大的在前面
    最后再将这个字符串转化为long long类型的数值就好了

代码

class Solution 
public:
    long long smallestNumber(long long num) 
        if(!num) return 0;
        bool fg = false;
        if(num < 0) fg = true,num = -num;
        string s = to_string(num);
        int n = s.size();
        if(fg)  sort(s.begin(),s.end(),greater<char>());
        else    sort(s.begin(),s.end());
        if(s[0] == '0')
            int i = 0;
            while(++i < n) if(s[i] != '0')
                swap(s[i],s[0]);
                break;
            
        
        long long ans = 0;
        for(int i = 0;i < n; ++i) ans = ans * 10 + s[i]-'0';
        if(fg) ans = -ans;
        return ans;
    
;

C.设计位集(模拟)

难度

⭐⭐

思路

因为考虑到只有一些字符串的0、1的更改,所以我们可以用一个num来记录1的数量,然后用一个fp来记录反转的次数(记得toString的时候更新),那么对于初始化,直接加上size个0即可,对于fix()unfix()操作我们需要关注几个点:

  • 1.反转的次数
  • 2.当前位置的字符
  • num的值是否更改
    我们根据这个不同的情况分类讨论即可,具体请看下面的代码
    对于all()操作和one()以及count()操作由于我们有一个num变量存储,所以直接输出即可
    对于toString()的操作我们就需要将反转的操作更新,然后反转次数归零,然后返回更新后的字符串
    详情请看代码

代码

class Bitset 
public:
    string s;
    int l;
    int num_1 = 0;
    int fp = 0;
    Bitset(int size) 
        s="";
        for(int i = 0;i < size; ++i) s+='0';
        l = size;
    
    
    void fix(int idx) 
        if(idx < l)
            if(fp & 1)
                if(s[idx] == '1') num_1++,s[idx]='0';
            else
                if(s[idx] == '0') num_1++,s[idx]='1';
            
        
    
    
    void unfix(int idx) 
        if(idx < l)
            if(fp & 1)
                if(s[idx] == '0') num_1--,s[idx]='1';
            
            else
                if(s[idx] == '1') num_1--,s[idx]='0';
            
        
    
    
    void flip() 
        fp++;
        num_1 = l - num_1;
    
    
    bool all() 
        return num_1 == l;
    
    
    bool one() 
        return num_1 > 0;
    
    
    int count() 
        return num_1;
    
    
    string toString() 
        for(int i = 0;i < l; ++i) 
            if(fp & 1)
                if(s[i] == '1') s[i] = '0';
                else s[i] = '1';
            
        
        fp=0;
        return s;
    
;

/**
 * Your Bitset object will be instantiated and called as such:
 * Bitset* obj = new Bitset(size);
 * obj->fix(idx);
 * obj->unfix(idx);
 * obj->flip();
 * bool param_4 = obj->all();
 * bool param_5 = obj->one();
 * int param_6 = obj->count();
 * string param_7 = obj->toString();
 */

D.移除所有载有违禁货物车厢所需的最少时间(前缀和+DP)

难度

⭐⭐⭐

思路

我们将列车分成两部分,枚举一下列车的分界处,然后分别计算前缀的最少花费时间和后缀的最少话费时间,我们能得到前缀的状态转移:

  • 如果 S [ i ] = = ′ 1 ′ S[i]=='1' S[i]==1,则 p r e [ i ] = m i n ( p r e [ i − 1 ] + 2 , i + 1 ) pre[i] = min(pre[i-1] + 2,i+1) pre[i]=min(pre[i1]+2,i+1)
  • 如果 S [ i ] = = ′ 0 ′ S[i]=='0' S[i]==0,则 p r e [ i ] = p r e [ i − 1 ] pre[i] = pre[i-1] pre[i]=pre[i1]
    后缀 s u f suf suf同理,注意的是,我们在进行前缀和的时候需要对0做一个特殊处理
    我们来理解一下 p r e [ i ] pre[i] pre[i]的含义:移除前i个所有载有违禁货物车厢所需的最少时间,我们有两种操作,要么从前一种状态转移过来,然后花费2单位时间删掉第i个车厢,或者就直接把前i个车厢全部删完,那么我们就得到了 S [ i ] = = ‘ 1 ’ S[i]==‘1’ S[i]==1的情况,对于 S [ i ] = ′ 0 ′ S[i]='0' S[i]=0的情况说明当前这个车厢是安全的,那么它不需要做任何操作,所以直接从前一个状态转移过来

代码

class Solution 
public:
    #define N 200005
    #define INF 0x3f3f3f3f
    int minimumTime(string s) 
        int suf[N]=0,pre[N]=0;
        int n = s.size();
        for(int i = n - 1;i >= 0; --i) 
            if(s[i] == '1') suf[i] = min(suf[i+1]+2,n-i);
            else suf[i] = suf[i+1];
        
        int ans = INF;
        for(int i = 0;i < n; ++i) 
            if(i)
                if(s[i] == '1')
                    pre[i] = min(pre[i-1]+2,i+1);
                else 
                    pre[i] = pre[i-1];
            
            else
                if(s[i] == '1') pre[i] = 1;
                else pre[i] = 0;
            
            ans = min(pre[i]+suf[i+1],ans);
        
        return ans;
    
;

以上是关于Leetcode第 279 场周赛的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode第 303 场周赛

LeetCode第 303 场周赛

LeetCode第 303 场周赛

LeetCode第302场周赛

LeetCode第302场周赛

LeetCode第302场周赛