本题是第138场周赛的Q4,LC竞赛分为1702。方法是 贪心+计数+排序。
方法一. 暴力(超时)
用 cnt 数组记录每一个元素的出现次数,从大到小排序,注意到每一次取 cnt[0] 与 cnt[1] 对应的元素放入答案数组中可以得到题目要求的答案。代码如下:
class Solution {
public:
static bool compare(pair<int,int>& a,pair<int,int>& b){
return a.second > b.second;
}
vector<int> rearrangeBarcodes(vector<int>& barcodes)
{
if(barcodes.size()==1) return barcodes;
vector<int> a(10001,0);
for(int i=0;i<barcodes.size();i++){
a[barcodes[i]]++;
}
vector<pair<int,int>> a1;
for(int i=0;i<10001;i++){
if(a[i]){
pair<int,int> tmp = {i,a[i]};
a1.push_back(tmp);
}
}
sort(a1.begin(),a1.end(),compare);
vector<int> res;
while(a1[0].second>0){
res.push_back(a1[0].first);
a1[0].second--;
if(a1[1].second>0){
res.push_back(a1[1].first);
a1[1].second--;
}
sort(a1.begin(),a1.end(),compare);
}
return res;
}
};
一共要取 O(n) 次数,每次取数进行一次排序,排序复杂度为 O(nlogn),总的复杂度为 O(n^2logn),超出了题目的要求。
方法二. 优化排序方法
注意到我们可以通过以下排序规则进行排序:先对答案 vector 的偶数下标填入数字,然后再对答案 vector 的奇数下标填入数字,以天然地达到间隔填数的要求,这样就可以避免每次填数之后都要重新排序这种浪费时间的操作。代码如下:
class Solution {
public:
static bool compare(pair<int,int>& a,pair<int,int>& b){
return a.second > b.second;
}
vector<int> rearrangeBarcodes(vector<int>& barcodes)
{
if(barcodes.size()==1) return barcodes;
vector<int> a(10001,0);
for(int i=0;i<barcodes.size();i++){
a[barcodes[i]]++;
}
vector<pair<int,int>> a1;
for(int i=0;i<10001;i++){
if(a[i]){
pair<int,int> tmp = {i,a[i]};
a1.push_back(tmp);
}
}
sort(a1.begin(),a1.end(),compare);
int n = barcodes.size();
vector<int> res(n,-1);
int i = 0;
int j = 0;
while(i<n){
res[i] = a1[j].first;
i+=2;a1[j].second--;
if(a1[j].second==0)
j++;
}
i=1;
while(i<n){
res[i] = a1[j].first;
i+=2;a1[j].second--;
if(a1[j].second==0)
j++;
}
return res;
}
};