zoukankan      html  css  js  c++  java
  • [LeetCode题解]23. 合并K个升序链表 | 分治 + 递归

    方法一:分治 + 递归

    解题思路

    21. 合并两个有序链表,我们知道如何合并两个有序链表。而本题是合并 k 个有序链表,可以通过大问题拆分成小问题解决,即把 k 个链表,拆分成 k/2 个链表组,俩俩合并,直到合并成一个链表,这就是分而治之的思想。

    可以通过递归来实现分治算法:

    1. 定义函数功能:合并链表数组中的 leftright 个链表
    2. 结束条件:left == right,即只剩下一个链表,无须合并,直接返回
    3. 递推公式:将 [left, right] 拆分成两半,分别获得左边已合并的链表 l1 和右边已合并的链表 l2,然后再对这两个链表进行合并。

    代码

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     public int val;
     *     public ListNode next;
     *     public ListNode(int val=0, ListNode next=null) {
     *         this.val = val;
     *         this.next = next;
     *     }
     * }
     */
    public class Solution {
        public ListNode MergeKLists(ListNode[] lists) {
            if(lists == null || lists.Length == 0) {
                return null;
            }
    
            return MergeKLists(lists, 0, lists.Length-1);
        }
    
        private ListNode MergeKLists(ListNode[] lists, int left, int right) {
            if(left == right) {
                return lists[left];
            }
            int mid = left + (right-left)/2;
            ListNode l1 = MergeKLists(lists, left, mid);
            ListNode l2 = MergeKLists(lists, mid+1, right);
    
            return MergeTwoLists(l1, l2);
        }
    
        private ListNode MergeTwoLists(ListNode l1, ListNode l2) {
            if(l1 == null) {
                return l2;
            }
            if(l2 == null) {
                return l1;
            }
    
            ListNode dummy = new ListNode();
            ListNode p1 = l1, p2 = l2, cur = dummy;
            while(p1 != null && p2 != null) {
                if(p1.val < p2.val) {
                    cur.next = p1;
                    cur = cur.next;
                    p1 = p1.next;
                } else {
                    cur.next = p2;
                    cur = cur.next;
                    p2 = p2.next;
                }
            }
    
            cur.next = p1 == null ? p2 : p1;
    
            return dummy.next;
        }
    }
    

    复杂度分析

    • 时间复杂度:(O(n*k*logk)),其中链表数组长度为 (k),链表的平均长度为 (n)。函数 MergeKLists 的时间复杂度为 (O(klogk))(分治),函数 MergeTwoLists 的时间复杂度是 (O(n)),因此总的时间复杂度为 (O(n*k*logk))
    • 空间复杂度:(O(logk)),递归会使用到 (O(logk)) 空间代价的栈空间。
  • 相关阅读:
    redis基本操作 —— hash
    redis基本操作 —— string
    redis —— linux下源码安装
    zookeeper c api 安装 & 连接 zookeeper
    wpa_supplicant移植(2.9版本)
    hostapd移植(2.6版本为例)
    hostapd移植(2.7版本)
    使用MKdocs搭建个人主页并关联到GithubPages上
    yolov5的yaml文件解析
    RANSAC——(RANdom SAmple Consensus(随机抽样一致))
  • 原文地址:https://www.cnblogs.com/liang24/p/14016191.html
Copyright © 2011-2022 走看看