代码随想录算法训练营第二天 |sort函数、 有序数组的平方 (LeetCode977)、长度最小的子数组(LeetCode209)、螺旋矩阵II(LeetCode59)
引用说明
文档讲解:代码随想录
sort函数:C++ Sort函数详解-CSDN博客
一、sort函数
1.sort函数调用的两种方式
默认: 两个参数
first
,last
,将[first, last)
区间内元素升序排列。【注意区间为左闭右开】自定义排序: 需用户指定排序规则
Compare comp
,将?[first, last)
区间内的元素按照用户指定的顺序排列。
2.sort函数排序原理
?sort()并非只是普通的快速排序,除了对普通的快速排序进行优化,它还结合了插入排序和堆排序。根据不同的数量级别以及不同情况,能自动选用合适的排序方法。当数据量较大时采用快速排序,分段递归。一旦分段后的数据量小于某个阀值,为避免递归调用带来过大的额外负荷,便会改用插入排序。而如果递归层次过深,有出现最坏情况的倾向,还会改用堆排序。
? 所以无论元素初始时为何种状态,sort()的平均排序复杂度为均为O(N*log2(N)) ,具有不错的的性能,在刷算法题时,可以直接使用sort()来对数据进行排序,而不需手动编写排序函数。
3.sort函数使用案例
升序排列
sort函数如果不传入第三个参数,则默认是升序排列。
#include<iostream>
#include<vector>
using namespace std;
int main() {
// 方式一、使用数组
int a[10] = {9, 6, 3, 8, 5, 2, 7, 4, 1, 0};
sort(a, a + 10); // 10为元素个数
for (int i = 0; i < 10; i++) cout << a[i] << ' '; // 输出排序后数组
cout << endl;
// 方式二、使用 vector
vector<int> arr = {9, 6, 3, 8, 5, 2, 7, 4, 1, 0};
sort(arr.begin(), arr.end()); // 10为元素个数
for (int i = 0; i < 10; i++) cout << arr[i] << ' '; // 输出排序后数组
return 0;
}
降序排列
a. ????????实现降序排列,需传入第三个参数–比较函数,
greater<type>()
,这里的元素为int
?类型,即函数为?greater<int>()
; 如果是其他基本数据类型如float
、double
、long
等也是同理。
#include<iostream>
#include<vector>
using namespace std;
int main() {
// 方式一、使用数组
int a[10] = {9, 6, 3, 8, 5, 2, 7, 4, 1, 0};
sort(a, a + 10, greater<int>()); // 10为元素个数
for (int i = 0; i < 10; i++) cout << a[i] << ' '; // 输出排序后数组
cout << endl; // 输出 9 8 7 6 5 4 3 2 1 0
// 方式二、使用 vector
vector<int> arr = {9, 6, 3, 8, 5, 2, 7, 4, 1, 0};
sort(arr.begin(), arr.end(), greater<int>());
for (int i = 0; i < 10; i++) cout << arr[i] << ' '; // 输出排序后数组
return 0;
}
b.????????我们也可以使用自定义的比较函数,函数的返回值为
bool
类型, 例如
bool cmp(int num1, int num2) {
return num1 > num2; // 可以简单理解为 > 降序排列; < 升序排列
}
#include<iostream>
#include<vector>
using namespace std;
bool cmp(int num1, int num2) {
return num1 > num2; // 可以简单理解为 >: 降序排列; < : 升序排列
}
int main() {
// 一、使用数组
int a[10] = {9, 6, 3, 8, 5, 2, 7, 4, 1, 0};
sort(a, a + 10, cmp); // 使用自定义排序函数
for (int i = 0; i < 10; i++) cout << a[i] << ' '; // 输出排序后数组
cout << endl; // 输出 9 8 7 6 5 4 3 2 1 0
// 二、使用 vector
vector<int> arr = {9, 6, 3, 8, 5, 2, 7, 4, 1, 0};
sort(arr.begin(), arr.end(), cmp); // 使用自定义排序函数
for (int i = 0; i < 10; i++) cout << arr[i] << ' '; // 输出排序后数组
return 0;
}
??结构体排序(自定义比较函数)
? 要对元素进行排序,前提是元素之间可以进行比较,即谁大谁小。 基本数据类型可直接进行大小比较, 但结构体元素之间的大小关系需要我们自己指定,如果不指定,则结构体之间大小关系就不确定,则不能够排序。
结构体排序案例1: 对学生信息进行排序
学生有
姓名
,分数
两个属性,
struct Student { // 学生结构体
string name; // 学生姓名
int grade; // 学生分数
Student(); // 无参数构造函数
Student(string name, int grade) : name(name), grade(grade) {}; // 有参数构造函数
};
需求:?对一个班级内的学生成绩进行排序,首先按成绩进行排序降序排列,若成绩相同,则按照姓名字典顺序升序排列。
- 自定义排序函数
bool cmp(Student s1, Student s2) { // 自定义排序
if (s1.grade != s2.grade) { // 如果学生成绩不相同
return s1.grade > s2.grade; // 则按照成绩降序排列
}
return s1.name < s2.name; // 否则按照姓名升序排列
}
- 排序代码
#include<iostream>
#include<vector>
using namespace std;
struct Student { // 学生结构体
string name; // 学生姓名
int grade; // 学生分数
Student(); // 无参数构造函数
Student(string name, int grade) : name(name), grade(grade) {}; // 有参数构造函数
};
bool cmp(Student s1, Student s2) { // 自定义排序
if (s1.grade != s2.grade) { // 如果学生成绩不同
return s1.grade > s2.grade; // 则按照成绩降序排列
}
return s1.name < s2.name; // 否则按照姓名升序排列
}
int main() {
vector<Student> studs;
studs.emplace_back("Bob", 80);
studs.emplace_back("Ali", 90);
studs.emplace_back("Ann", 85);
studs.emplace_back("Liming", 90);
studs.emplace_back("Trump", 79);
studs.emplace_back("Fury", 58);
studs.emplace_back("Jam", 62);
studs.emplace_back("Lucy", 89);
sort(studs.begin(), studs.end(), cmp); // 排序
for (int i = 0; i < studs.size(); i++) { // 输出结果
cout << studs[i].name << "\t" << studs[i].grade << endl;
}
return 0;
}
4.自定义comp函数返回true或false作用
自定义函数返回值为
bool
类型
- 若返回
true
,则表示num1
?与num2
应该交换顺序;- 若返回
false
, 则num1
?与num2
?保持原有顺序;下面举例说明自定义比较函数的执行过程。
对 2, 5, 1, 3, 4 降序排列
调用cmp函数时,将5赋值给num1, 2赋值给num2 (注意顺序)
5 > 2, 返回true,num1 与 num2需进行交换;即5应该在2的前面
数组变为 5, 2, 1, 3, 4
第二次 将3赋值给num1, 1赋值给num2,
3 > 1, 返回true,num1 与 num2需进行交换;即3应该在1的前面
数组变为 5, 2, 3, 1, 4
之后经过数次的比较与交换最终排序完成。
最终得到 5 4 3 2 1
二、有序数组的平方
暴力解
遍历每个元素,并对每个元素进行平方。再对整个数组进行快速排序
vector<int> sortedSquares(vector<int>& nums) {
for(int i = 0; i < nums.size(); i++){
nums[i] = nums[i] * nums[i];
}
sort(nums.begin(), nums.end());
return nums;
}
双指针法
?类似快排的交换思想
vector<int> sortedSquares(vector<int>& nums) {
vector<int> result(nums.size(), 0);
int k = nums.size() - 1;
for(int i = 0, j = nums.size() - 1 ; i <= j;){
if(nums[i] * nums[i] < nums[j] * nums[j]){
result[k--] = nums[j] * nums[j];
j--;
}else{
result[k--] = nums[i] * nums[i];
i++;
}
}
return result;
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!