ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

7.单链表的六大解题套路

2022-05-17 21:34:27  阅读:148  来源: 互联网

标签:p2 head 单链 ListNode 套路 p1 next 链表 解题


单链表的六大解题套路

合并两个有序链表

将两个升序链表合并为一个新的升序链表并返回,新链表是通过拼接给定的两个链表的所有节点组成的

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(-1),p = dummy;//虚拟头结点
        ListNode p1=l1,p2=l2;
        while(p1!=null&&p2!=null){//比较p1和p2两个指针
				//将值较小的节点接到p指针
            if(p1.val>p2.val){
                p.next=p2;
                p2=p2.next;
            }else{
                p.next=p1;
                p1=p1.next;
            }
            p=p.next;//p指针不断前进
        }
        if(p1!=null){
            p.next=p1;
        }
        if(p2!=null){
            p.next=p2;
        }
        return dummy.next;
    }

Untitled

while循环每次比较p1和p2的大小,把较小的节点接到结果链表上

链表算法题,很常见的【虚拟头结点】技巧,就是dummy节点,有了这个占位符,可以避免处理空指针的情况,降低代码复杂性

合并k个有序链表?

逻辑类似合并两个有序链表,难点在于,如何快速得到 k 个节点中的最小节点,接到结果链表上?

用到优先级队列(二叉堆)这种数据结构,把链表节点放入一个最小堆,就可以每次获得 k 个节点中的最小节点

public ListNode mergeKLists(ListNode[] lists) {
        if(lists.length == 0)return null;
        ListNode dummy = new ListNode(-1), p = dummy;//虚拟头结点
				//优先级队列,最小堆?
        PriorityQueue<ListNode> pq = new PriorityQueue<>(
            lists.length,(a,b)->(a.val - b.val)
        );
				//将 k 个链表的头结点加入最小堆
        for(ListNode head : lists){
            if(head != null){
                pq.add(head);
            }
        }
        while(!pq.isEmpty()){
            ListNode node = pq.poll();//获取最小节点,接到结果链表中
            p.next = node;
            if(node.next!=null){
                pq.add(node.next);
            }
            p=p.next;//p指针不断前进
        }
        return dummy.next;
    }

优先队列 pq 中的元素个数最多是k,所以一次 poll或者 add方法的时间复杂度是O(logk)所有的链表节点都会被加入和弹出 pq,所以算法整体的算法复杂度是O(Nlogk),其中 k 是链表的条数,N是这些链表的节点总数

单链表的倒数第k个节点

从前往后寻找单链表第 k 个节点很简单,一个for循环遍历过去就找到了

Untitled

让快指针指向链表头结点 head,先走 k 步

Untitled

再用一个慢指针指向链表头结点head

让快慢指针同时向前走,快指针走到链表末尾的空指针,走了n-k步,那慢指针也走了n-k步,也就是链表的倒数第k个节点。

//返回链表的倒数第 k 个节点
ListNode findFromEnd(ListNode head,int k){
	ListNode p1 = head, p2 = head;
	for(int i=0; i < k;i++){
		p1 = p1.next;
	}
	
	while(p1 != null){
		p2 = p2.next;
		p1 = p1.next;.
	}
	return p2;
}

无论遍历一次链表和遍历两次链表的时间复杂度都是O(N),但是上述算法更有技巧性

删除链表的倒数第N个结点

public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode fast,slow;
        fast =slow = head;
        while(n-- > 0){
            fast = fast.next;
        } 
        if(fast == null){
            return head.next;
        }
        while(fast!=null && fast.next != null){
            fast = fast.next;
            slow = slow.next;
        }
        slow.next = slow.next.next;
        return head;
    }
public ListNode removeNthFromEnd(ListNode head, int n) {
       ListNode dummy = new ListNode(-1);
       dummy.next = head;
       ListNode x = findFromEnd(dummy,n+1);
       x.next = x.next.next;
       return dummy.next;
    }

    private ListNode findFromEnd(ListNode head,int k){
        ListNode p1 =head,p2 =head;
        for(int i =0;i< k;i++){
            p1= p1.next;
        }
        while(p1!=null){
            p1= p1.next;
            p2=p2.next;
        }
        return p2;
    }

单链表的中点

Untitled

解决这个问题的关键是,通过某些方式,让p1和p2能够同时到达相交节点

Untitled

让两个指针分别遍历两个链表,相当于【逻辑上】两条链表接在一起,可以让两个指针,同时进入公共部分,也就是同时到达相交节点。

如果没有相交点,相当于c1节点是null空指针,可以正确返回null

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode p1 =headA,p2 = headB;
        while(p1!=p2){
            if(p1 == null) p1 = headB;
            else p1 = p1.next;
            if(p2 == null)p2 = headA;
            else p2 = p2.next;
        }
        return p1;
    }

标签:p2,head,单链,ListNode,套路,p1,next,链表,解题
来源: https://www.cnblogs.com/autumnmoonming/p/16282440.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有