面试中LeetCode常见算法整理——排序

面试中LeetCode常见算法整理——排序

快速排序

用于求解 Kth Element 问题,使用快速排序的 partition() 进行实现。需要先打乱数组,否则最坏情况下时间复杂度为 O(N2)。

堆排序

用于求解 TopK Elements 问题,通过维护一个大小为 K 的堆,堆中的元素就是 TopK Elements。
堆排序也可以用于求解 Kth Element 问题,堆顶元素就是 Kth Element。
快速选择也可以求解 TopK Elements 问题,因为找到 Kth Element 之后,再遍历一次数组,所有小于等于 Kth
Element 的元素都是 TopK Elements。
可以看到,快速选择和堆排序都可以求解 Kth Element 和 TopK Elements 问题。

1. Kth Element

215. Kth Largest Element in an Array

思路一:排序

时间复杂度 O(NlogN),空间复杂度 O(1)。

class Solution {
public:
    int findKthLargest(vector& nums, int k) {
        assert(k>=1&&k<=nums.size());
        sort(nums.begin(), nums.end());
        return nums[nums.size()-k];
    }
};

思路二:优先队列

时间复杂度 O(NlogK),空间复杂度 O(K)。

class Solution {
public:
	int findKthLargest(vector& nums, int k) {
		priority_queue, greater> pq;
		for (int i = 0; i < nums.size(); ++i)
		{
			pq.push(nums[i]);
			if (pq.size() > k) //维护优先队列大小为k,保证队列中第k个元素最小
				pq.pop();
		}
		return pq.top();
	}
};

思路三:快速排序思想

时间复杂度 O(N),空间复杂度 O(1)

class Solution1 {
public:
	int findKthLargest(vector& nums, int k) {
		assert(k >= 1 && nums.size() >= k);
		srand(time(NULL));
		return findKthLargest(nums, 0, nums.size() - 1, k - 1);
	}

private:
	int findKthLargest(vector& nums, int l, int r, int k)
	{
		if (l == r)
			return nums[l];
		int p = partition(nums, l, r);
		if (p == k)
			return nums[p];
		else if (p < k)
			return findKthLargest(nums, p + 1, r, k);
		else
			return findKthLargest(nums, l, p - 1, k);
	}

	//从大到小排序
	int partition(vector& nums, int l, int r)
	{
		swap(nums[l], nums[rand() % (r - l + 1) + l]);
		int v = nums[l];
		//[l+1, gt]>v, (gt,i)<=v
		int gt = l;
		int i = l + 1;
		while (i <= r)
		{
			if (nums[i] > v)
				swap(nums[i], nums[++gt]);
			++i;
		}
		swap(nums[l], nums[gt]);
		return gt;
	}
};

 2. 出现频率最多的 k 个数

347. Top K Frequent Elements

class Solution {
public:
	vector topKFrequent(vector& nums, int k) {
		unordered_map m; //存储<值,频率>对儿
		for (auto num : nums)
			++m[num];
		assert(m.size() >= k); //保证有至少k个不同的元素
		//优先队列中存储的<频率,值>对儿
		priority_queue, vector>, greater>> pq;
		for (auto it = m.begin(); it != m.end(); ++it)
		{
			pq.push(make_pair(it->second, it->first));
			if (pq.size() > k) //注意此处条件的使用,可以避免元素比较;如果是==的话,还需多一次比较操作
				pq.pop();
		}
		vector res;
		while (!pq.empty())
		{
			res.push_back(pq.top().second);
			pq.pop();
		}
		return res;
	}
};

3. 按照字符串出现次数对字符串排序

451. Sort Characters By Frequency

class Solution {
public:
    string frequencySort(string s) {
        if(s=="")
            return s;
        unordered_map record;
        for(int i = 0;i>vRecord(record.begin(), record.end());
        sort(vRecord.begin(), vRecord.end(), pair_cmp);
        string res = "";
        for(int i = 0;i &lhs,const pair &rhs)
    {
        return lhs.second>rhs.second;
    }
};

4. 荷兰国旗问题

75. Sort Colors

本质是三路快速排序思想。

class Solution {
public:
    void sortColors(vector& nums) {
        //[0, zero] == 0
        int zero = -1;
        //[two, n-1] == 2;
        int n = nums.size();
        int two = n;
        int i = 0;
        while(i

 

你可能感兴趣的:(LeetCode刷题之路,算法研讨之路)