[算法]【刷题笔记】链表专题

必备知识

链表是一种兼具递归和迭代性质的数据结构,常用技巧:双指针中的快慢指针。

一、合并两个有序链表(虚拟头结点)

/**

 * Definition for singly-linked list.

 * public class ListNode {

 *     int val;

 *     ListNode next;

 *     ListNode() {}

 *     ListNode(int val) { this.val = val; }

 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }

 * }

 */

class Solution {

    public ListNode mergeTwoLists(ListNod

e list1, ListNode list2) {

        ListNode result = new ListNode();// 使用虚拟头结点:第一个节点为空,从第二个节点开始才是想要的

        ListNode p = result;

        ListNode p1 = list1,p2 = list2;

        while(p1 != null && p2!=null) {

            if(p1.val > p2.val) {

                p.next = p2;

                p2 = p2.next;

            } else {

                p.next = p1;

                p1 = p1.next;

            }

            p = p.next;

        }

        while(p1 != null) {

            p.next = p1;

            p1 = p1.next;

            p = p.next;

        }

        while (p2 != null) {

            p.next = p2;

            p2= p2.next;

            p = p.next;

        }

        return result.next;

    }

}

解题思路:

合并两个单链表:

1.使用双指针循环遍历,两个单链表同时遍历比较;然后移动指针

2.两个单链表同时遍历完后,最多会剩下一个单链表还有值,需要将剩下的也合并。

3.两个单链表都需要判断一下是否为空,不空就合并,最后返回合并后的链表

4.可以使用虚拟头结点进行辅助

二、合并K个有序链表(虚拟头结点和二叉堆)

/**

 * Definition for singly-linked list.

 * public class ListNode {

 *     int val;

 *     ListNode next;

 *     ListNode() {}

 *     ListNode(int val) { this.val = val; }

 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }

 * }

 */

class Solution {

    public ListNode mergeKLists(ListNode[] lists) {

        ListNode result = new ListNode();

        ListNode temp = result;

        if(lists.length == 0) {

            return null;

        }

        PriorityQueue<ListNode> minHead = new PriorityQueue<>(lists.length, Comparator.comparingInt(o -> o.val));

        for (ListNode node: lists

             ) {

            if (node != null){

                minHead.offer(node);

            }

        }

        while (!minHead.isEmpty()) {

            ListNode node = minHead.poll();

            temp.next = node;

            if (node.next != null) {

                minHead.offer(node.next);

            }

            temp = temp.next;

        }

        return result.next;

    }

}

解题思路:

  1. 分析题目,合并K个有序的链表,则需要找出这K个链表中最小的那个节点,使用优先队列-二叉堆-最小堆得特性,辅助
  2. 创建一个虚机头结点的结果链表
  3. 遍历将K个链表先放进优先队列中,因为是有序的,则第一批放进去的肯定存在最小的节点
  4. 再一个个出队列,第一个出队的就是最小,将最小的节点放到结果链表中,然后再将最小节点的下一个节点放进优先队列中进行排序
  5. 最后将
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值