排序相关总结

快排:
挖坑填数 + 分治
复杂度:最快O(nlog(n)),最慢O(n^2)

void quick_sort(vector<int> &nums, int left, int right)
{
	if(left < right)
	{
		int i = left, j = right, key = nums[left];
		while(i < j)
		{
			while(i < j && nums[j] >= key)
				j--;
			nums[i] = nums[j];
			while(i < j && nums[i] <= key)
				i++;
			nums[j] = nums[i];
		}
		nums[i] = key;
		quick_sort(nums, left, i - 1);
		quick_sort(nums, i + 1, right);
	}
}

归并排序:
分为排好序的两部分 + 合并

void merge_sort(vector<int> &nums, int l, int r, vector<int> &temp)
{
	if(l < r)
	{
		int mid = (l + r) >> 1;
		merge_sort(nums, l, mid, temp);
		merge_sort(nums, mid + 1, r, temp);
		int i = l, j = mid + 1, t = l;
		while(i < mid + 1 && j < r + 1)
		{
			if(nums[i] < nums[j])
				temp[t++] = nums[i++];
			else
				temp[t++] = nums[j++];
		}
		while(i < mid + 1)
		{
			temp[t++] = nums[i++];
		}
		while(j < r + 1)
		{
			temp[t++] = nums[j++];
		}
		t = l;
		while(t < r + 1)
		{
			nums[t] = temp[t];
			t++;
		}
	}
}

堆排序:堆排序讲解

void max_heapify(vector<int> &nums, int start, int end)		//大顶堆调整
{
	int dad = start;
	int son = dad * 2 + 1;
	while(son <= end)
	{
		if(son + 1 <= end && nums[son] < nums[son + 1])	//比较两个子节点谁更大
			son++;
		if(nums[dad] >= nums[son])
			return;
		else									//交换完后,需要进一步判断交换后的孩子树是否满足大顶堆条件
		{
			swap(nums[dad], nums[son]);		
			dad = son;
			son = dad * 2 + 1;
		}
	}
}
void heap_sort(vector<int> &nums, int len)
{
	for (int i = len / 2 - 1; i >= 0; i--)	//对于无序数组,先对每个父节点进行大顶堆调整
		max_heapify(nums, i, len - 1);
	for (int i = len - 1; i > 0;i--)
	{
		swap(nums[i], nums[0]);				//交换第一个与最后一个值
		max_heapify(nums, 0, i - 1);		//对无序的根节点nums[0]在i - 1范围内进行大顶堆调整
	}
}

215.数组中的第k个最大元素
题解:可以采用快速选择即快速排序的子过程,寻找大于某个元素的数的个数等于k。可以采用二分法进行逐步判断。也可以采用大顶堆排序,寻找第k个大的元素。

//二分 + 快速选择
class Solution {
public:
    int quick_select(vector<int> &nums, int left, int right)
    {

            int i = left, j = right, key = nums[i];
            while(i < j)
            {
                while(i < j && nums[j] >= key)
                    j--;
                nums[i] = nums[j];
                while(i < j && nums[i] <= key)
                    i++;
                nums[j] = nums[i];
            }
            nums[i] = key;
            return i;

    }
    int findKthLargest(vector<int>& nums, int k) {
        if(nums.size() == 1)
        {
            return nums[0];
        }
        int l = 0, r = nums.size() - 1;
        int n;
        while(l < r)
        {
            n = quick_select(nums, l, r);
            if(nums.size() - n == k)
               return nums[n];
            else if (nums.size() - n < k)
                r = n - 1;
            else
                l = n + 1;
        }
        return nums[r];
    }       
};
//大顶堆排序
class Solution {
public:
    void max_heapify(vector<int> &nums, int start, int end)
    {
        int dad = start;
        int son = dad * 2 + 1;
        while(son <= end)
        {
            if(son + 1 <= end && nums[son] < nums[son + 1])
                son++;
            if(nums[dad] > nums[son])
                return;
            else
            {
                swap(nums[dad], nums[son]);
                dad = son;
                son = dad * 2 + 1;
            }
        }
    }
    int findKthLargest(vector<int>& nums, int k) {
        int len = nums.size();
        for(int i = len / 2 - 1; i >= 0 ; i--)
            max_heapify(nums, i, len - 1);
        int numb = 0;
        for(int i = len - 1;i >= 0; i--)
        {
            swap(nums[i], nums[0]);
            numb++;
            if(numb == k)
                return nums[i];
            max_heapify(nums, 0, i - 1);
        }
        return 0;	//无用
    }       
};

347.前k个高频元素
题解:可以采用优先队列,对元素出现的个数进行排序,从得到最终结果。也可以采用桶排序将出现次数作为二维数组的下标,即可统计得到以下标为出现次数,值为元素的二维数组,然后按条件输出结果即可。

//优先队列
class Solution {
public:
class mycompare
{
    public:
    bool operator()(const pair<int, int> &a, const pair<int, int> &b)
    {
        return a.second > b.second;
    }
};
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int, int> m;
        for(int i = 0;i<nums.size(); i++)
            ++m[nums[i]];
        priority_queue<pair<int, int>, vector<pair<int, int>>, mycompare> pq;
        for(auto const &p: m)
        {
            pq.push(p);
            if(pq.size() > k)
            {
                pq.pop();
            }
        }
        vector<int> res;
        for(int i = 0;i<k;i++)
        {
            res.push_back(pq.top().first);
            pq.pop();
        }
        return res;
    }
};
//桶排序
class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int, int> m;
        int max_count = 0;
        for(int i = 0;i<nums.size();i++)
            max_count = std::max(max_count, ++m[nums[i]]);
        vector<vector<int>> v(max_count + 1);
        for(auto const &p: m)
        {
            v[p.second].push_back(p.first);
        }
        vector<int> res;
        for(int i = max_count; i>= 0 && res.size() < k;i--)
        {
            for(auto const &p : v[i])
            {
                res.push_back(p);
                if(res.size() == k)
                    break;
            }
        }
        return res;
    }
};

75.颜色分类
题解:采用双指针p0 p2,遍历数组,nums[i] 若等于0则将nums[p0]与nums[i]交换,若等于2则将nums[i]与nums[p2]交换,在交换2时会出现将两个都为2的值进行交换的情况,因此需要循环交换,直到p2指向非2值或等于i

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int p0 = 0, p2 = nums.size() - 1;
        for(int i = 0;i<nums.size();i++)
        {
            while(i < p2 && nums[i] == 2)
            {
                swap(nums[i], nums[p2]);
                p2--;
            }
            if(nums[i] == 0)
            {
                swap(nums[i], nums[p0]);
                p0++;
            }
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值