【算法集训专题攻克篇】第三篇之排序

算法集训传送门

  👉引言

在这里插入图片描述

铭记于心
🎉✨🎉我唯一知道的,便是我一无所知🎉✨🎉

💖 我们的算法之路💖

   众所周知,作为一名合格的程序员,算法 能力 是不可获缺的,并且在算法学习的过程中我们总是能感受到算法的✨魅力✨。
               ☀️🌟短短几行代码,凝聚无数前人智慧;一个普通循环,即是解题之眼🌟☀️
   💝二分,💝贪心,💝并查集,💝二叉树,💝图论,💝深度优先搜索(dfs),💝宽度优先搜索(bfs),💝数论,💝动态规划等等, 路漫漫其修远兮,吾将上下而求索! 希望在此集训中与大家共同进步,有所收获!!!🎉🎉🎉


今日主题:排序


 👉第一题💎

   ✨题目

      1636. 按照频率将数组升序排序

   ✨思路

将每种数看作一个点,那么这个数值就是点的id,出现的频率就是value值,那么就可以封装到一个类里,然后先将原数组转化成 点集,然后再按规则进行排序即可

   ✨代码
class Solution {
public:
    class p {
public:
	int id;
	int value;
};
vector<int> frequencySort(vector<int>& nums) {
	map<int, int>ans;
	for (int i = 0; i < nums.size(); i++) {
		ans[nums[i]]++;
	}
	vector<p>Ps;
	for (map<int, int>::iterator it = ans.begin(); it != ans.end(); it++) {
		p pt;
		pt.id = it->first;
		pt.value = it->second;
		Ps.push_back(pt);
	}
	sort(Ps.begin(), Ps.end(), [](p p1, p p2) {return p1.value == p2.value ? p1.id > p2.id:p1.value < p2.value; });
	vector<int>ANS;
	for (p tem : Ps) {
		int r = tem.id;
		for (int i = 0; i < tem.value; i++) {
			ANS.push_back(r);
		}
	}
	return ANS;
}
};

 👉第二题💎

   ✨题目

      1287. 有序数组中出现次数超过25%的元素

很简单,只需要统计一下各种数出现的次数即可,这里使用STL的map,其实用数组更快些(为了“节省空间”,还是用map),也可以直接遍历一遍找频率最大的那个数

   ✨代码
class Solution {
public:
   int findSpecialInteger(vector<int>& arr) {
	double n = arr.size();
	map<int, int>ans;
	for (int i = 0; i < arr.size(); i++) {
		int t=++ans[arr[i]];
		if (t / n > 0.25)return arr[i];
	}
	return -1;
}
};

 👉第三题💎

   ✨题目

      1464. 数组中两元素的最大乘积

   ✨思路

从大到小排序,然后输出前两个乘积

   ✨代码
class Solution {
public:
    int maxProduct(vector<int>& nums) {
	sort(nums.begin(), nums.end(),greater<int>());
	return (nums[0] - 1) * (nums[1] - 1);
}
};

 👉第四题💎

   ✨题目

      436. 寻找右区间

   ✨思路

这道题最主要的就是,在原区间数组的基础上将下标属性加进去后再复制出来一个,然后一个按照左端点排序,另一个按照右端点,最后遍历的时候,以右端点区间数组intervals为主,去找是否存在满足条件(左端点大于等于右端点的“右侧”数组),如果存在,则将该右侧数组下标加到res集合中,最后返回res

   ✨代码
class Solution {
public:
    vector<int> findRightInterval(vector<vector<int>>& intervals) {
	for (int i = 0; i < intervals.size(); i++) {
		intervals[i].push_back(i);
	}
	vector<int>res(intervals.size(), -1);
	vector<vector<int>>intervals_plus = intervals;
	sort(intervals_plus.begin(), intervals_plus.end(), [](vector<int>t1, vector<int>t2) {return t1[0] < t2[0]; });
	sort(intervals.begin(), intervals.end(), [](vector<int>t1, vector<int>t2) {return t1[1] < t2[1]; });
	int j = 0;
	for (int i = 0; i < intervals.size(); i++) {
		int pi = intervals[i][2];
		for (; j < intervals_plus.size(); j++)
		{
			int pj = intervals_plus[j][2];
			if (intervals_plus[j][0] >= intervals[i][1]) {
				res[pi] = pj;
				break;
			}
		}
	}
	return res;
}
};

  💎总结💎

今天的题目主要是排序,可以利用STL的sort函数,内部使用了快排,堆排,插入排序等,我们可以通过Lambda表达式进行深入定制,该思想在上述代码中有很好的体现。需要注意的是最后一题,我们可以搞出两个数组分别进行不同的排序规则,通过下标属性来定位。


写在最后
相信大家对今天的集训内容的理解与以往已经有很大不同了吧,或许也感受到了算法的魅力,当然这是一定的,路漫漫其修远兮,吾将上下而求索!伙伴们,明天见!

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦想new的出来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值