LeetCode 870. 优势洗牌

LeetCode 870. 优势洗牌_第1张图片

方法一:贪心算法(超时)

田忌赛马的思想:对于每个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;
    }
};

方法二:快排+贪心算法

方法一的时间复杂度为 O ( n 2 ) O(n^2) O(n2),部分数据超时因此要想办法降低时间复杂度。我们考虑到 O ( n 2 ) O(n^2) O(n2)的时间耗费在找数组中的最小值上,因此,我们想到先用快排对数组排序,降低时间复杂度为 O ( n l o g ) O(nlog) O(nlog)用结构体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;
    }
};

你可能感兴趣的:(LeetCode)