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[i−1]+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[i−1]
后缀 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 场周赛的主要内容,如果未能解决你的问题,请参考以下文章