Leetcode_堆(1)23 合并k个排序链表,215 数组中的第K个最大元素

目录

23.合并k个排序链表 H

215. 数组中的第K个最大元素


23.合并k个排序链表 H

合并 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

输入:
[
  1->4->5,
  1->3->4,
  2->6
]
输出: 1->1->2->3->4->4->5->6

方法 1:暴力

想法 & 算法

  • 遍历所有链表,将所有节点的值放到一个数组中。
  • 将这个数组排序,然后遍历所有元素得到正确顺序的值。
  • 用遍历得到的值,创建一个新的有序链表。

方法 2:逐一比较

算法

  • 比较 k 个节点(每个链表的首节点),获得最小值的节点。
  • 将选中的节点接在最终有序链表的后面。

复杂度分析

  • 时间复杂度: O(kN), 其中 k 是链表的数目。

    • 几乎最终有序链表中每个节点的时间开销都为 O(k) (k-1 次比较)。
    • 总共有 N 个节点在最后的链表中。
  • 空间复杂度:

    • O(n) 。创建一个新的链表空间开销为 O(n)O(n) 。
    • O(1) 。重复利用原来的链表节点,每次选择节点时将它直接接在最后返回的链表后面,而不是创建一个新的节点。

方法 3:用优先队列优化方法 2

算法

几乎与上述方法一样,除了将 比较环节 用 优先队列 进行了优化。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    struct cmp{  //对新的数据类型的<进行重写
       bool operator()(ListNode *a,ListNode *b){
          return a->val > b->val;
       }
    };
    ListNode* mergeKLists(vector<ListNode*>& lists) {
       priority_queue<ListNode* ,vector<ListNode*> , cmp> heapk;
       for(auto p:lists){
        if(p!=NULL){
            heapk.push(p);
        }
       }
       ListNode *pHead = new ListNode(-1);
       ListNode *pCur = pHead;
       while(!heapk.empty()){
          ListNode *top = heapk.top();heapk.pop();
          pCur->next = top;
          pCur = pCur->next;
          if(top->next!=NULL){
            heapk.push(top->next);
          } 
       }
       pCur = pHead->next;
       delete pHead;
       return pCur;
    }
};

方法 5:分治

想法 & 算法

  • 将 k 个链表配对并将同一对中的链表合并。
  • 第一轮合并以后,  k 个链表被合并成了 k/2​ 个链表,平均长度为 2N​/k ,然后是k/4​ 个链表,k/8​ 个链表等等。
  • 重复这一过程,直到我们得到了最终的有序链表。

因此,我们在每一次配对合并的过程中都会遍历几乎全部 N 个节点,并重复这一过程 log2​K 次。

类似归并排序的回溯过程,两两合并。  O(Nlog2K)   

public class Test {
	public ListNode mergeKLists(ListNode[] lists) {
		PriorityQueue<ListNode> pq = new PriorityQueue<>(new Comparator<ListNode>() {
			@Override
			public int compare(ListNode o1, ListNode o2) {
				return o1.val - o2.val;
			}
		});
		for(ListNode e : lists) {
			if(e!=null)
				pq.add(e);
		}
		ListNode head = new ListNode(0);
		head.next = null;
		ListNode tail = head;
		while(!pq.isEmpty()) {
			tail.next = pq.poll();
			tail = tail.next;
			if(tail.next!=null) {
				pq.add(tail.next);
			}
			tail.next = null;
		}
		return head.next;
	}
}

215. 数组中的第K个最大元素

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int,vector<int>,greater<int>> q;
        for(auto it:nums){
            q.push(it);
            if(q.size()>k) q.pop();
        }
        return q.top();
    }
};


 

发布了88 篇原创文章 · 获赞 77 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43107805/article/details/104963584