506. Relative Ranks的C++解法

本文探讨了一种基于快速排序算法的竞赛排名实现方案,并提出了一种更优解——利用优先队列和pair组合来提高效率。文章详细介绍了两种方法的具体实现过程及注意事项。

本质就是一个排序问题。考虑到时间复杂度的问题选择了快排,但是好像不是很方便。需要一个额外的索引数组,出于题目限制还要有一个记录原始顺序的数组。感觉空间开销稍微大一点。不过速度还是挺快的。

class Solution {
public:
	vector<int> id;
	void quickSort(vector<int>& s, int l, int r){
		if (l < r)
		{
			int i = l, j = r, x = s[l], p = id[l];
			while (i < j)
			{
				while (i < j && s[j] <= x) j--;
				if (i < j)
				{
					id[i] = id[j];
					s[i++] = s[j];
				}
				while (i < j && s[i] > x) i++;
				if (i < j)
				{
					id[j] = id[i];
					s[j--] = s[i];
				}
			}
			s[i] = x;
			id[i] = p;
			quickSort(s, l, i - 1);
			quickSort(s, i + 1, r);
		}
	}
	vector<string> findRelativeRanks(vector<int>& nums) {
		vector<int>copy;
		vector<string> result;
		result.resize(nums.size());
		for (int i = 0; i < nums.size(); i++)
		{
			id.push_back(i);
			copy.push_back(nums[i]);
		}
		quickSort(nums, 0, nums.size()-1);
		result[id[0]] = "Gold Medal";
		if (nums.size()>1){
			result[id[1]] = "Silver Medal";
			if (nums.size() > 2){
				result[id[2]] = "Bronze Medal";
				for (int i = 3; i < nums.size(); i++)
				{
					result[id[i]] = to_string(i+1);
				}
			}
		}
		
		return result;
	}
};

1.快排的时候注意索引数组也要跟着改变和调整。这个时候有个写法问题,如s[i++]=s[j],赋值的同时i值也变了,再执行id[i]=id[j]其实是错的。

2.返回最终结果之前判断上下界,有时候人数小于3并没有银牌、铜牌什么的

3.vector数组不可以直接对下标进行操作(没有开辟空间),如果想这么做要先resize到足够大小。


这个算法感觉比较拧巴,又写了一个按照自己思路来的插排。本来想着可以只改变rank数组不改变原始数组,但当前面的已排数据不是按照升序的话会出现错误(1,3,2,5,4)


最优解算法:

使用了优先队列和make_pair。

优先队列在push入每一个元素的时候都会进行动态调整,使得队列的top都是队列中的最大值。make_pair可以理解为将两个关联起来。

class Solution {
public:
    vector<string> findRelativeRanks(vector<int>& nums) {
        priority_queue<pair<int,int> > pq;
        for(int i=0;i<nums.size();i++)
        {
            pq.push(make_pair(nums[i],i));
        }
        vector<string> res(nums.size(),"");
        int count = 1;
        for(int i=0; i<nums.size();i++)
        {
            if(count==1) {res[pq.top().second] = "Gold Medal"; count++;}
            else if(count==2) {res[pq.top().second] = "Silver Medal"; count++;}
            else if(count==3) {res[pq.top().second] = "Bronze Medal"; count++;}
            else {res[pq.top().second] = to_string(count); count++;}
            pq.pop();
        }
        return res;
    }
};




评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值