LeetCode 870. 优势洗牌
程序员文章站
2024-02-13 14:00:04
...
方法一:贪心算法(超时)
对于每个B[i]
,找到比其大的最小A[j]
,若不存在,则用最小的A[j]
抵消
class Solution {
public:
vector<int> advantageCount(vector<int>& A, vector<int>& B) {
int len=A.size();
for(int i=0;i<len;i++){
int min_dif=INFINITY,min_j=-1;
for(int j=i;j<len;j++)//找比B[i]大的最小数字
if(A[j]>B[i]){
int dif=A[j]-B[i];
if(min_dif>dif)
min_dif=dif,min_j=j;
}
if(min_j==-1){//没有比B[i]大的数字,找最小的A[j]抵消
int min_num=INFINITY;
for(int j=i;j<len;j++)
if(min_num>A[j])
min_num=A[j],min_j=j;
}
swap(A[i],A[min_j]);
}
return A;
}
};
方法二:快排+贪心算法
方法一的时间复杂度为,部分数据超时因此要想办法降低时间复杂度。我们考虑到的时间耗费在找数组中的最小值上,因此,我们想到先用快排对数组排序,降低时间复杂度为。用结构体node
解决B
排序数据复原的功能
class Solution {
private:
struct node{
int key,value;
};
static bool cmp_value(node A,node B){//一定要改为静态函数
return A.value<B.value;
}
static bool cmp_key(node A,node B){
return A.key<B.key;
}
public:
vector<int> advantageCount(vector<int>& A, vector<int>& B) {
int len=A.size();
node b[len];
for(int i=0;i<len;i++)
b[i].key=i,b[i].value=B[i];
sort(A.begin(),A.end()); sort(b,b+len,cmp_value);
int la=0,lb=0,rb=len-1;
while(la<len){//配对,覆盖b.value
if(A[la]>b[lb].value) b[lb++].value=A[la++];//有优势
else b[rb--].value=A[la++];//无优势
}
sort(b,b+len,cmp_key);//根据key值重新进行排序
for(int i=0;i<len;i++)//将b.value转换为vector形式返回
B[i]=b[i].value;
return B;
}
};