排序算法
排序
baixiaofei567
如果十年前没种树,那最好的时间是现在
展开
-
剑指offer——最小的K个数C++
现在的Partion法并不能AC有三种方法:1.sort之后,返回vector(input.begin().input.begin()+k);即可2.前一种用了sort,时复为O(NlogN),不行。因为是要k个最小的数,我们应该想到维护一个k个元素的大顶堆,当堆满的时候,将堆顶元素和想要插入进来的元素进行比较,如果比堆顶元素小,就弹出堆顶元素并加入当前元素,内部自动会帮你排序。我们可以用multiset<int,greater>或者priority_queue来实现堆。multiset.原创 2020-12-28 00:29:59 · 114 阅读 · 0 评论 -
手写七大排序以及注释(C++)
#include<iostream>#include<vector>#include<ctime>using namespace std;//选择排序,每次选择最小的元素,将它与数组的第一个元素交换位置,再再从数组剩下的元素中选择出最小的元素,将它与第二个元素交换位置。不断进行这样的操作,直到将整个数组排序 //就算有序也要O(n^2)时复 //不稳定 void Select_sort(vector<int>& nums){ //最后原创 2021-03-06 13:11:56 · 214 阅读 · 0 评论 -
451. 根据字符出现频率排序
堆排就是击败5%。这些和出现次数有关的还是得用桶排序效率比较高。就是根据出现次数最多的max开一个二维数组,二维数组的大小是max+1。这样我们就可以按照出现次数将对应的数字放入那个桶中,然后从大到小遍历所有桶即可。class Solution {public: // struct cmp{ // bool operator()(const pair<char,int>& a, const pair<char,int>& b){ .原创 2021-02-19 02:03:14 · 97 阅读 · 0 评论 -
378. 有序矩阵中第 K 小的元素
二分肯定写不出,太难了。法一:加入数组后sort然后取出下标为k-1的法二:维护一个大小为k的大顶堆,如果比栈顶小,就加入,最后剩下的就是k个最小的元素,栈顶就是第k小的元素class Solution {public: int kthSmallest(vector<vector<int>>& matrix, int k) { //行列都升序排序,要找第k小的元素 //左上是最小的,1,1,8,第二小的元素还是1 .原创 2021-02-17 01:15:35 · 106 阅读 · 0 评论 -
315. 计算右侧小于当前元素的个数
需要二刷的题,细节满满class Solution {public: void mergeSort(int left, int right, vector<int>& index, vector<int>& nums, vector<int>& fuzhu){ if(left == right) return;//当切分到只有一个数字时结束切分 int mid = left + (right-left).原创 2021-02-16 01:25:25 · 95 阅读 · 0 评论 -
88. 合并两个有序数组
法一:需要额外空间的归并排序。法二:不需要额外空间的反向归并排序。class Solution {public: void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) { //因为最后合并的数组只要nums1的前m个元素 //所以我们把前m个元素存一下,然后归并排序放入nums1中 // vector<int> num.原创 2021-02-05 00:55:36 · 84 阅读 · 0 评论 -
21. 合并两个有序链表
新建一个h结点作为新链表的头(哨兵结点),要new不要初始化为nullptr,来一个cur来在链表上移动。遍历两条链表,只要一条空就结束遍历,用cur的next指向未空的另一条链表即可。将比较小的那个结点直接拷贝构造,是深拷贝等于新建一个结点,而不是指向l1,不然会改变l1的指向。并将cur指向next,l1也往后走一步。l2同理。最后返回哨兵的next/** * Definition for singly-linked list. * struct ListNode { * int v..原创 2021-01-18 01:56:21 · 79 阅读 · 0 评论 -
347. 前 K 个高频元素
topk问题,不是大顶堆就是小顶堆。直接上优先队列,这里要自定义比较函数。维护出现频率最高的k个元素,我们维护一个k个元素的小顶堆,为什么用小顶堆,因为出现频率最少的可以在堆顶,每次新进来的元素优先和堆顶的比,如果比堆顶的出现频率高,堆顶的就可以被pop了,加入新的。最后留下的k个元素就是频率最高的k个。class Solution {public: struct cmp{ bool operator()(const pair<int,int>& a, co.原创 2021-01-29 10:21:06 · 78 阅读 · 0 评论 -
75. 颜色分类
三路快排的思想,省去了切分操作,直接一遍遍历。如果当前位是0,就替换到最左边,并把i和left都++,如果为2,就替换到最右边,并把right–,但是i不能++,因为替换过来的值没有检查过。如果为1就不变i++。直到I>right退出循环,等于不能退出,比如2,0,1,如果right等于i了,那么102直接退出了。class Solution {public: void sortColors(vector<int>& nums) { //用三路快排,1.原创 2021-01-26 01:50:21 · 58 阅读 · 0 评论 -
23. 合并K个升序链表
1.暴力法:遍历每一条链表,将每个结点加入vector,然后对vector进行sort,cmp的用法是如果返回值为1就不交换。最后遍历链表,创建新链表即可,重点是将最后tmp的next设为空指针!!必须必须,链表结尾必须为空2.分治法:归并排序,写一个切分函数,再写一个merge函数,因为数组中存的是链表的头,而每一条链表又是有序的,所以当我们切分到一个结点时,就当做切分完毕,只剩一条链表就是有序的(和只剩一个元素就算是有序的右异曲同工之妙)。left和right相等时就是切分完毕,返回lists[l..原创 2021-01-19 01:51:21 · 122 阅读 · 0 评论 -
215. 数组中的第K个最大元素
sort很快,但不能用。归排还可以写,我大概知道我的归排之前错在哪里了,i大于mid或者j大于right马上退出循环,然后把另外一边没有搞定的加入数组class Solution {public: //归排,从中点切分,左右都是闭区间 void mergeSort(vector<int>& nums, int left, int right){ if(left == right) return;//此时该区间只有一个数字,证明切分到最小了 .原创 2021-01-11 00:30:10 · 63 阅读 · 0 评论 -
148. 排序链表(归并排序)
用归并排序给链表排序快慢指针,慢一步快两步,快到终点了,慢也到终点或者中点的左边了。设置一个tmp为切分点(slow)下一个,将slow的next设为空,相当于把链表一分为二。左链表等于递归排序左边,将head传进去即可,右链表递归右边传入tmp。定义一个h为当前链表头=cur,cur一直往前,左小于等于右,就插入左到cur后面,反之右。最后结束后一定有一边没遍历完,将整条链表插在cur后面,cur指向非空的头即可。最后返回h->next/** * Definition for singl..原创 2021-01-09 01:59:33 · 225 阅读 · 1 评论 -
剑指offer——数组中的逆序对C++(75%)
非常好的题,利用了归并排序的特性。#include<vector>class Solution {public: //cop[left...mid]是有序的,cop[mid+1...right]是有序的 /*int mergeAndCount(vector<int>& cop, int left, int mid, int right, vector<int>& fuzhu){ //先全放入辅助数组中,然后按序放回原.原创 2020-12-30 01:52:21 · 255 阅读 · 0 评论 -
剑指offer——调整数组顺序使奇数位于偶数前面
不难,难的是要写出最完美的方法,这里用了三种,如果实在不行第一种总写得出的第一种:时复O(n),空复O(n),开辟一个额外数组用于辅助,遍历两次碰到奇数就直接push_back进去,第二次碰到偶数就push_back进去。或者碰到奇数直接放进去,然后从后往前,碰到偶数就从后往前放。第二种:O(n^2)和O(1),冒泡排序,从前往后找到奇数就在循环内部往前遍历,如果遍历到奇数就直接break,因为按理说前面的奇数已经被处理完了,前面奇数的前面是不会有偶数的。如果遍历到偶数,就慢慢swap过去,将当前位j.原创 2020-12-24 02:05:29 · 118 阅读 · 0 评论 -
排序算法(自我学习)
原创 2020-11-06 22:22:22 · 135 阅读 · 0 评论 -
1098 Insertion or Heap Sort (25分)
According to Wikipedia:Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list. Each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, an原创 2020-11-05 01:23:22 · 69 阅读 · 0 评论 -
1089 Insert or Merge (25分)
According to Wikipedia:Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list. Each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, an原创 2020-11-02 01:24:09 · 101 阅读 · 0 评论 -
优先队列&堆排序
优先队列原创 2020-08-17 15:08:29 · 144 阅读 · 0 评论 -
快速排序
快速排序引人注目的特点包括它是原地排序(只需要一个很小的辅助栈)且长度为N的数组排序所需的时间和NlgN成正比缺点:非常脆弱,需要小心才能避免低劣的性能。基本算法快排是一种分治的算法,快排把数组切分成两个小数组,切分点左侧的都比切分点小,右侧的都比切分点大,左右子数组均有序,大数组也就有序了。class Quick{ public: void quick_sort(int a[]){ random.shuffle(a,a+a.size());//消除对输入的依赖 sort(a,0,原创 2020-08-15 23:21:30 · 95 阅读 · 0 评论 -
归并排序
归并即将两个有序的数组归并成一个更大的有序数组。**优点:**能够保证将任意长度为N的数组排序所需时间和NlogN成正比。**缺点:**所需的额外空间和N成正比。原地归并的抽象方法实现归并的一种直接了当的方法是将两个不同的有序数组归并到第三个数组中。实现方法就是创建一个适当大小的数组,将两个数组一个个从小到大放入大数组中。但是!!!当用归并将一个大数组排序时,需要进行多次归并,每次归并都创建一个新数组就太浪费内存了。所以需要原地归并,这样就可以先将前半部分排序,再将后半部分排序。下面的代码还是用原创 2020-08-13 23:41:33 · 115 阅读 · 0 评论 -
初级排序算法
选择排序在数组中找到最小的元素,将其和第一个元素交换位置。再从剩下的元素中找到最小的元素,和第二个元素交换位置。如此往复,直到将整个数组排序,这种方法叫选择排序,因为它在不断地选择元素之间的最小者。每次交换都排定一个元素,所以交换的总次数为N。所以算法的时间效率取决于比较的次数class solution{ void sort(int compare[]){ int N = compare.size(); for(int i = 0; i<N; i++) { int min原创 2020-08-13 11:44:54 · 93 阅读 · 0 评论