LeetCode 数据流中的第K大元素(优先队列)

设计一个找到数据流中第K大元素的类(class)。注意是排序后的第K大元素,不是第K个不同的元素。

你的 KthLargest 类需要一个同时接收整数 k 和整数数组nums 的构造器,它包含数据流中的初始元素。每次调用 KthLargest.add,返回当前数据流中第K大的元素。
示例:

int k = 3;
int[] arr = [4,5,8,2];
KthLargest kthLargest = new KthLargest(3, arr);
kthLargest.add(3);   // returns 4
kthLargest.add(5);   // returns 5
kthLargest.add(10);  // returns 5
kthLargest.add(9);   // returns 8
kthLargest.add(4);   // returns 8

说明:
你可以假设 nums 的长度≥ k-1 且k ≥ 1。
思路分析: 首先我的思路是想着怎么排序,每次都插入一个元素,为此选择插入排序,插入后再返回第k大元素。

class KthLargest {
public:
	int k = 1;
	list<int> myList;//降序链表
	KthLargest(int k, vector<int>& nums) {
		this->k = k;
        //将所有元素依次插入
		for (auto num : nums) {
			auto it = myList.begin();
			while (it != myList.end() && *it > num) {
				it++;
			}
			it = myList.insert(it, num);
		}
	}

	int add(int val) {
        //第一步找到插入的位置
		auto it = myList.begin();
		while (it != myList.end() && *it > val) {
			it++;
		}
		myList.insert(it, val);//插入
        //然后找到第K大元素
		it = myList.begin();
		int tempK = k;
		while (tempK-- > 1) {
			it++;
		}
		return *it;
	}
};

/**
 * Your KthLargest object will be instantiated and called as such:
 * KthLargest* obj = new KthLargest(k, nums);
 * int param_1 = obj->add(val);
 */

这样时间复杂度为O(n),空间复杂度为O(n)。
LeetCode 数据流中的第K大元素(优先队列)_第1张图片
但是在一个已经排好序的元素中插入的应该使用二分法,时间复杂度为O(log2n)。

class KthLargest {
public:
	int k = 1;
	multiset<int> mySet;//集合自带排序
	KthLargest(int k, vector<int>& nums) {
		this->k = k;
		//将所有元素依次插入
		for (auto num : nums) {
			mySet.insert(num);
		}
	}

	int add(int val) {
		mySet.insert(val);//插入到集合
        //获取第K大的元素
		auto it = mySet.end();
		int tempK = k;
		while (tempK-- > 0) {
			it--;
		}
		return *it;
	}
};

/**
 * Your KthLargest object will be instantiated and called as such:
 * KthLargest* obj = new KthLargest(k, nums);
 * int param_1 = obj->add(val);
 */

蛋式还是超时了。。
下面将维护一个大小为k的升序优先队列,这队首就是第K大元素。

class KthLargest {
public:
    int myK = 1;
	priority_queue<int, vector<int>, greater<int>> myPriorityQue;//按降序排列的优先队列
	KthLargest(int k, vector<int>& nums) {
        myK = k;
		//将所有元素依次插入
		for (auto num : nums) {
			myPriorityQue.push(num);
		}
		//维持队列的大小为k
        while (myPriorityQue.size() > k){
            myPriorityQue.pop();
        }
	}

	int add(int val) {
        if (myPriorityQue.size() == myK){
            //只有当队列大小为k时,才需要考虑是否需要pop元素
            if (val > myPriorityQue.top()){
                //只有当队首小于val,这val才能该表第K大元素
                myPriorityQue.pop();
                myPriorityQue.push(val);
            }
        }
        else{
            //否则直接放入
            myPriorityQue.push(val);
        }
        return myPriorityQue.top();//当前队首就是第K大元素
	}
};

/**
 * Your KthLargest object will be instantiated and called as such:
 * KthLargest* obj = new KthLargest(k, nums);
 * int param_1 = obj->add(val);
 */

LeetCode 数据流中的第K大元素(优先队列)_第2张图片

你可能感兴趣的:(LeetCode,队列)