首页 > 其他分享 >【合并排序链表】分治/优先队列

【合并排序链表】分治/优先队列

时间:2023-12-14 21:01:16浏览次数:26  
标签:ListNode val 队列 分治 lists next 链表 int null

合并两个排序链表

  • 模拟维护一个合并链表,每次添加两个排序链表中较小val的节点即可
模拟代码
    public ListNode mergeTwo(ListNode a, ListNode b) {
        if(a == null) return b;
        if(b == null) return a;
        ListNode ans = new ListNode(0);
        ListNode ans0 = ans;
        while(a != null && b != null) {
            if(a.val <= b.val) {
                ans.next = new ListNode(a.val, null);
                a = a.next;
            } else {
                ans.next = new ListNode(b.val, null);
                b = b.next;
            }
            ans = ans.next;
        }
        if(a != null) {
            ans.next = a;
        } else {
            ans.next = b;
        }
        return ans0.next;
    }

合并K个排序链表

leetcode 23. 合并 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) {
        int len = lists.length;
        ListNode ans = null;
        for(int i = 0; i < len; ++ i ) {
            ans = mergeTwo(ans, lists[i]);
        }
        return ans;
    }

    public ListNode mergeTwo(ListNode a, ListNode b) {
        if(a == null) return b;
        if(b == null) return a;
        ListNode ans = new ListNode(0);
        ListNode ans0 = ans;
        while(a != null && b != null) {
            if(a.val <= b.val) {
                ans.next = new ListNode(a.val, null);
                a = a.next;
            } else {
                ans.next = new ListNode(b.val, null);
                b = b.next;
            }
            ans = ans.next;
        }
        if(a != null) {
            ans.next = a;
        } else {
            ans.next = b;
        }
        return ans0.next;
    }
}

分治合并

  • 基于两两合并,再分治思想递归合并链表数组
分治合并代码
/**
 * 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) {
        return merge(lists, 0, lists.length - 1);
    }

    public ListNode merge(ListNode[] lists, int l, int r) {
        if(l == r) return lists[l];
        // 边界值:lists.length = 0会出现 l>r
        if(l > r) return null;
        int mid = l + ((r - l) >> 1);
        
        return mergeTwo(merge(lists, l, mid), merge(lists, mid + 1, r));
    }

    public ListNode mergeTwo(ListNode a, ListNode b) {
        if(a == null) return b;
        if(b == null) return a;
        ListNode ans = new ListNode(0);
        ListNode ans0 = ans;
        while(a != null && b != null) {
            if(a.val <= b.val) {
                ans.next = new ListNode(a.val, null);
                a = a.next;
            } else {
                ans.next = new ListNode(b.val, null);
                b = b.next;
            }
            ans = ans.next;
        }
        if(a != null) {
            ans.next = a;
        } else {
            ans.next = b;
        }
        return ans0.next;
    }
}

使用优先队列合并

使用优先队列维护两个排序链表中的值,然后按照优先队列中升序元素构造新的合并链表即可

使用优先队列合并代码
/**
 * 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) {
        int len = lists.length;
        Queue<Integer> pq = new PriorityQueue<>();
        for(int i = 0; i < len; ++ i ) {
            while(lists[i] != null) {
                pq.offer(lists[i].val);
                lists[i] = lists[i].next;
            }
        }
        ListNode head, tail;
        head = tail = null;
        while(!pq.isEmpty()) {
            int val = pq.poll();
            if(head == null) head = tail = new ListNode(val, null);
            else {
                tail.next = new ListNode(val, null);
                tail = tail.next;
            }
        }
        return head;
    }
}

标签:ListNode,val,队列,分治,lists,next,链表,int,null
From: https://www.cnblogs.com/Eve7Xu/p/17901924.html

相关文章

  • 【删除链表的倒数第N个节点】双指针
    leetcode19.删除链表的倒数第N个结点题解1:通过链表长度获取[倒数第n个节点]位置计算链表长度找到[倒数第N个节点]的前一个节点删除[倒数第N个节点]注意特殊情况:删除的是第一个节点时,直接返回第二个节点即可点击查看代码/***Definitionforsingly-linkedlist.......
  • 记录rabbitMQ的广播队列的错误使用导致未能正确广播的问题
    背景说明:有3个服务S1、S2、S3现在服务S1需要发布消息到广播交换机E,并建立了两个普通队列Q1,Q2,将其绑定到广播交换机E上服务S2和服务S3同时监听队列Q1,Q2本意是,服务S1通过广播交换机E把消息同时推送给服务S2和S3后面测试时,同事发现,服务S2和服务S3都只接收到了部分消息,而不是全......
  • 【大数相加链表模拟】
    leetcode2.两数相加题意:两个长度为[1,100]的大数,分别倒序存储(个位在链表头)在两个链表中,计算两个数的和,并倒序存储在一个新链表,返回链表表头。数据中不存在前导零。题解:模拟大数相加,注意维护进位carry即可代码/***Definitionforsingly-linkedlist.*publicclassL......
  • 清空ActiveMQ中的Scheduled延时队列
    要清空ActiveMQ中的Scheduled延时队列,可以执行以下步骤:停止ActiveMQ服务器。在ActiveMQ数据存储目录中找到存储延时消息的目录。该目录的默认位置是<activemq_home>/data/localhost/Scheduled.删除该目录下的所有文件,这将清空延时队列中的消息。启动ActiveMQ服务器。请注意......
  • Java中的消息队列(MQ)应用实践
    摘要:本文将介绍Java中消息队列(MQ)的概念、应用场景以及如何使用Java中的消息队列进行实践。我们将探讨如何使用Java消息队列实现异步通信、解耦和流量削峰等常见需求,并通过实际案例展示其应用。一、引言在分布式系统中,消息队列(MQ)是一种常见的中间件技术,用于实现异步通信和解耦。通过......
  • 【回文链表】快慢指针+反转链表
    leetcode234.回文链表题意:判断一个链表是不是回文(中心对称)的【反转链表】题解1:得到原链表的反转链表,然后对比原链表与反转链表的内容是否一致即可。反转链表版本代码/***Definitionforsingly-linkedlist.*publicclassListNode{*intval;*ListNo......
  • 241. 为运算表达式设计优先级(分治 +记忆化)
    Problem:241.为运算表达式设计优先级给你一个由数字和运算符组成的字符串expression,按不同优先级组合数字和运算符,计算并返回所有可能组合的结果。你可以按任意顺序返回答案。生成的测试用例满足其对应输出值符合32位整数范围,不同结果的数量不超过示例1:输入:expression=......
  • 【反转链表】while循环/递归
    leetcode206.反转链表题意:给定链表表头,反转链表,返回反转链表的表头【循环】题解:head维护原链表当前节点,nHead维护反转链表的头节点,nHead置于head前一位,依次后移,直至head到链表尾结束。双指针循环版本/***Definitionforsingly-linkedlist.*publicclassListNode......
  • 数据结构:双链表
    由于双链表中大部分操作其实和单链表操作类似,所以这里只挑关键的一些函数1、定义与初始化typedefstructDNode{ElementTypedata;structDNode*prior,*next;}DNode,*DLinkList;boolInitialDLinkList(DLinkList&L){L=(DNode*)malloc(sizeof(DNode));......
  • 阻塞队列linkedBlockQuene和syncroBlockQuene的区别?
    在Java中,LinkedBlockingQueue和SynchronousQueue是两种不同类型的阻塞队列,它们有一些关键的区别:实现机制:LinkedBlockingQueue使用一个链表实现的有界或无界队列。有界队列的容量是固定的,而无界队列的容量理论上是无限的。SynchronousQueue是一个特殊的阻塞队列,它在内部......