双指针技巧秒杀七道链表题目(1)
双指针技巧秒杀七道链表题目
对于单链表相关的题目,双指针的运用是非常广泛的
例如:
1、合并两个有序链表
2、合并 k
个有序链表
3、寻找单链表的倒数第 k
个节点
4、寻找单链表的中点
5、判断单链表是否包含环并找出环起点
6、判断两个单链表是否相交并找出交点
合并两个有序链表
最基本的链表技巧,力扣第 21 题「 合并两个有序链表」
class Solution {
public:
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
// 虚拟头结点
ListNode* dummy = new ListNode(-1);
ListNode* p=dummy;
ListNode* p1=list1;
ListNode* p2=list2;
while(p1!=nullptr&&p2!=nullptr){
if(p1->val>p2->val){
p->next=p2;
p2=p2->next;
}else{
p->next=p1;
p1=p1->next;
}
p=p->next;
}
if(p1!=nullptr){
p->next=p1;
}
if(p2!=nullptr){
p->next=p2;
}
return dummy->next;
}
};
代码中还用到一个链表的算法题中是很常见的「虚拟头结点」技巧,也就是 dummy
节点。如果不使用 dummy
虚拟节点,代码会复杂很多,而有了 dummy
节点这个占位符,可以避免处理空指针的情况,降低代码的复杂性。
合并 k 个有序链表
我的思路:让链表两两合并,类似合并两个链表。
class Solution {
public:
ListNode* mergeTwoLists(ListNode* p1,ListNode* p2){
if((!p1)||(!p2)) return p1?p1:p2;
ListNode* dummy=new ListNode();
ListNode* p=dummy;
ListNode* p3=p1;
ListNode* p4=p2;
while(p3!=nullptr&&p4!=nullptr){
if(p3->val>p4->val){
p->next=p4;
p4=p4->next;
}else{
p->next=p3;
p3=p3->next;
}
p=p->next;
}
p->next=p3?p3:p4;
return dummy->next;
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode* p=nullptr;
for(int i=0;i<lists.size();i++){
p=mergeTwoLists(p,lists[i]);
}
return p;
}
};
但是这样的时间复杂度与空间复杂度并不理想,因此可以考虑使用优先级队列(二叉堆)这种数据结构,把链表节点放入一个最小堆,就可以每次获得 k
个节点中的最小节点
C++代码:
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
//lambda
//因为lambda的类型是由编译器自动解析的,所以你不需要考虑像参数的类型是函数 指针或函数之类的事情。
//无论如何,decltype(...)都会解析为可调用的对象。
//lambda 二叉堆每次top放最小的 放进来的是b,
auto compare=[](ListNode* a,ListNode* b){
return a->val>=b->val;
};
//使用优先级队列(二叉堆)实现
priority_queue<ListNode*,vector<ListNode*>,decltype(compare)>pq(compare);
//虚拟头节点
ListNode* dummy=new ListNode(-1);
ListNode* p=dummy;
//将k个链表的头节点加入最小堆
for(ListNode* head:lists){
if(head!=nullptr){
pq.push(head);
}
}
while(!pq.empty()){
//获得最小节点,接到结果链表中
ListNode* node=pq.top();
pq.pop();
p->next=node;
if(node->next!=nullptr){
pq.push(node->next);
}
//p指针不断前进
p=p->next;
}
return dummy->next;
}
};
本文来自博客园,作者:{BailanZ},转载请注明原文链接:https://www.cnblogs.com/BailanZ/p/16095523.html