LeetCode:23. Merge k Sorted Lists(K个链表进行排序)

本文深入解析了LeetCode上寻找第K大元素的问题,提供了两种高效的算法解决方案,包括递归的二路归并排序和优先级队列方法。详细介绍了每种方法的实现步骤和代码示例,旨在帮助读者理解和掌握解决此类问题的有效途径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章最前: 我是Octopus,这个名字来源于我的中文名--章鱼;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github ;这博客是记录我学习的点点滴滴,如果您对 Python、Java、AI、算法有兴趣,可以关注我的动态,一起学习,共同进步。

相关文章:

  1. LeetCode:55. Jump Game(跳远比赛)
  2. Leetcode:300. Longest Increasing Subsequence(最大增长序列)
  3. LeetCode:560. Subarray Sum Equals K(找出数组中连续子串和等于k

文章目录:

题目描述:

java方法1:(利用类似的二路归并排序,递归的方式)

python实现方式1:

源码github地址:https://github.com/zhangyu345293721/leetcode


题目描述:

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5

示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4

说明:

你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。


著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


java方法1:(利用类似的二路归并排序,递归的方式)

   /**
     * @param lists 要合并的链表
     * @return 链表
     */
    public ListNode mergeKLists(ListNode[] lists) {
        if (lists == null || lists.length < 1) {
            return null;
        }
        return helper(lists, 0, lists.length - 1);
    }

    /**
     * 终止条件是l和r相等
     *
     * @param lists 链表
     * @param l     左边
     * @param r     右边
     * @return 合并后链表
     */
    private ListNode helper(ListNode[] lists, int l, int r) {
        if (l == r) {
            return lists[l];
        }
        int mid = (l + r) / 2;
        return merge(helper(lists, l, mid), helper(lists, mid + 1, r));
    }

    /**
     * 通过指针合并两个链表
     *
     * @param l1 链表1
     * @param l2 链表2
     * @return 合并两个链表
     */
    private ListNode merge(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(-1);
        ListNode tail = dummy;
        while (l1 != null && l2 != null) {
            if (l1.val < l2.val) {
                tail.next = l1;
                l1 = l1.next;
            } else {
                tail.next = l2;
                l2 = l2.next;
            }
            tail = tail.next;
        }
        if (l1 != null) {
            tail.next = l1;
        }
        if (l2 != null) {
            tail.next = l2;
        }
        return dummy.next;
    }

时间复杂度:O(logn.n)

空间复杂度:O(n)


python实现方式1:

from typing import List

from list.linked_list_cycle2_142 import ListNode



def helper(lists: List[ListNode], l: int, r: int) -> ListNode:
    '''
        递归帮助类
    Args:
        lists: 链表
        l: 坐标
        r: 右边
    Returns:
       合并后链表
    '''
    if l == r:
        return lists[l]
    mid = (l + r) / 2
    return merge(helper(lists, l, mid), helper(lists, mid + 1, r))


def merge_k_list(lists: List[ListNode]) -> ListNode:
    '''
        熟悉合并链表
    Args:
        lists:链表
    Returns:
        合并后的list
    '''
    if not lists:
        return None
    return helper(lists, 0, len(lists) - 1)

def merge(l1: ListNode, l2: ListNode) -> ListNode:
    dummy = ListNode(-1)
    tail = dummy
    while l1 != None and l2 != None:
        if l1.val < l2.val:
            tail.next = l1
            l1 = l1.next
        else:
            tail.next = l2
            l2 = l2.next
        tail = tail.next
    if l1 != None:
        tail.next = l1
    if l2 != None:
        tail.next = l2
    return dummy.next

时间复杂度:O(logn.n)

空间复杂度:O(n)


java方法2:

/**
 * 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) {
        if(lists == null || lists.length < 1) {
            return null;
        }
        PriorityQueue<ListNode> queue = new PriorityQueue(
            new Comparator<ListNode>() {
            @Override
            public int compare(ListNode q1, ListNode q2) {
            return q1.val - q2.val;
            }
        }
        );
        int k = lists.length;
        for(int i = 0;i < k; i++) {
            if(lists[i] != null ){
                queue.offer(lists[i]);
            }
        }
        ListNode dummy = new ListNode(-1);
        ListNode tail = dummy;
        while(!queue.isEmpty()){
            ListNode cur = queue.poll();
            tail.next = cur;
            tail = tail.next;
            if(cur.next != null) {
                queue.offer(cur.next);
            }
        }
        return dummy.next;
    }
}

时间复杂度:O(logn.n)

空间复杂度:O(n)


python方法2:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
import heapq

class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        dummy = ListNode(0)
        p = dummy
        head = []
        k = len(lists)
        for i in range(k):
            if lists[i] :
                heapq.heappush(head, (lists[i].val, i))
                lists[i] = lists[i].next
        while head:
            val, idx = heapq.heappop(head)
            p.next = ListNode(val)
            p = p.next
            if lists[idx]:
                heapq.heappush(head, (lists[idx].val, idx))
                lists[idx] = lists[idx].next
        return dummy.next

时间复杂度:O(logn.n)

空间复杂度:O(n)


源码github地址:

GitHub - zhangyu345293721/leetcode: java/python for leetcode

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值