LeetCode 23: Merge k Sorted Lists

LeetCode 23: Merge k Sorted Lists

    • [1. 📌 Problem Links](#1. 📌 Problem Links)
    • [2. 🧠 Solution Overview](#2. 🧠 Solution Overview)
    • [3. 🟢 Solution 1: Min-Heap (Priority Queue)](#3. 🟢 Solution 1: Min-Heap (Priority Queue))
      • [3.1. Algorithm Idea](#3.1. Algorithm Idea)
      • [3.2. Key Points](#3.2. Key Points)
      • [3.3. Java Implementation](#3.3. Java Implementation)
      • [3.4. Complexity Analysis](#3.4. Complexity Analysis)
    • [4. 🟡 Solution 2: Divide and Conquer (Merge Sort Style)](#4. 🟡 Solution 2: Divide and Conquer (Merge Sort Style))
      • [4.1. Algorithm Idea](#4.1. Algorithm Idea)
      • [4.2. Key Points](#4.2. Key Points)
      • [4.3. Java Implementation](#4.3. Java Implementation)
      • [4.4. Complexity Analysis](#4.4. Complexity Analysis)
    • [5. 🔵 Solution 3: Iterative Merge (Bottom-Up)](#5. 🔵 Solution 3: Iterative Merge (Bottom-Up))
      • [5.1. Algorithm Idea](#5.1. Algorithm Idea)
      • [5.2. Key Points](#5.2. Key Points)
      • [5.3. Java Implementation](#5.3. Java Implementation)
      • [5.4. Complexity Analysis](#5.4. Complexity Analysis)
    • [6. 📊 Solution Comparison](#6. 📊 Solution Comparison)
    • [7. 💡 Summary](#7. 💡 Summary)

2. 🧠 Solution Overview

This problem requires merging k sorted linked lists into one sorted linked list. The challenge is to do this efficiently, especially when k is large. Below are the main approaches:

Method Key Idea Time Complexity Space Complexity
Min-Heap (Priority Queue) Always extract minimum node O(n log k) O(k)
Divide and Conquer Merge lists in pairs recursively O(n log k) O(log k)
Brute Force Merge lists one by one O(nk) O(1)

3. 🟢 Solution 1: Min-Heap (Priority Queue)

3.1. Algorithm Idea

We use a min-heap (priority queue) to always get the smallest node among all current list heads. We repeatedly extract the smallest node, add it to the result list, and push its next node back into the heap if it exists.

3.2. Key Points

  • Heap Initialization: Add the first node of each list to the heap
  • Extract Minimum: Heap always gives us the smallest current node
  • Incremental Addition: After extracting a node, add its next node to heap
  • Dummy Node: Use dummy node to simplify list construction
  • Termination: Stop when heap is empty

3.3. Java Implementation

java 复制代码
/**
 * 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 == 0) return null;
        
        PriorityQueue<ListNode> minHeap = new PriorityQueue<>((a, b) -> a.val - b.val);
        
        // Add first node of each list to the heap
        for (ListNode list : lists) {
            if (list != null) {
                minHeap.offer(list);
            }
        }
        
        ListNode dummy = new ListNode(0);
        ListNode current = dummy;
        
        while (!minHeap.isEmpty()) {
            ListNode smallest = minHeap.poll();
            current.next = smallest;
            current = current.next;
            
            // Add next node from the same list to heap
            if (smallest.next != null) {
                minHeap.offer(smallest.next);
            }
        }
        
        return dummy.next;
    }
}

3.4. Complexity Analysis

  • Time Complexity : O(n log k) - Each of n nodes is inserted/extracted from heap of size k
  • Space Complexity : O(k) - Heap stores at most k nodes

4. 🟡 Solution 2: Divide and Conquer (Merge Sort Style)

4.1. Algorithm Idea

This approach treats the problem like merge sort. We recursively divide the k lists into halves, merge each half, and then merge the two halves together. This reduces the problem to multiple instances of merging two sorted lists.

4.2. Key Points

  • Recursive Division: Split lists array into left and right halves
  • Base Case: When only one list remains, return it
  • Merge Two Lists: Use standard two-list merging
  • Bottom-up Approach: Merge smallest pairs first

4.3. Java Implementation

java 复制代码
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if (lists == null || lists.length == 0) return null;
        return mergeLists(lists, 0, lists.length - 1);
    }
    
    private ListNode mergeLists(ListNode[] lists, int left, int right) {
        if (left == right) {
            return lists[left];
        }
        
        int mid = left + (right - left) / 2;
        ListNode leftList = mergeLists(lists, left, mid);
        ListNode rightList = mergeLists(lists, mid + 1, right);
        
        return mergeTwoLists(leftList, rightList);
    }
    
    private ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode current = dummy;
        
        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                current.next = l1;
                l1 = l1.next;
            } else {
                current.next = l2;
                l2 = l2.next;
            }
            current = current.next;
        }
        
        // Attach remaining nodes
        if (l1 != null) {
            current.next = l1;
        } else {
            current.next = l2;
        }
        
        return dummy.next;
    }
}

4.4. Complexity Analysis

  • Time Complexity : O(n log k) - Each node is merged log k times
  • Space Complexity : O(log k) - Recursion stack depth

5. 🔵 Solution 3: Iterative Merge (Bottom-Up)

5.1. Algorithm Idea

This is an iterative version of the divide and conquer approach. We merge lists in pairs repeatedly until only one list remains. This avoids recursion overhead and uses constant space.

5.2. Key Points

  • Pairwise Merging: Merge lists[0] with lists[1], lists[2] with lists[3], etc.
  • In-place Update: Store merged lists back in the array
  • Halving Strategy: Each iteration reduces number of lists by half
  • Iterative Control: Use while loop until only one list remains

5.3. Java Implementation

java 复制代码
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if (lists == null || lists.length == 0) return null;
        
        int n = lists.length;
        
        while (n > 1) {
            for (int i = 0; i < n / 2; i++) {
                lists[i] = mergeTwoLists(lists[i], lists[n - 1 - i]);
            }
            n = (n + 1) / 2; // Handle odd number of lists
        }
        
        return lists[0];
    }
    
    private ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode current = dummy;
        
        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                current.next = l1;
                l1 = l1.next;
            } else {
                current.next = l2;
                l2 = l2.next;
            }
            current = current.next;
        }
        
        if (l1 != null) current.next = l1;
        else current.next = l2;
        
        return dummy.next;
    }
}

5.4. Complexity Analysis

  • Time Complexity : O(n log k) - Same as recursive approach
  • Space Complexity : O(1) - No recursion stack, only iterative merging

6. 📊 Solution Comparison

Solution Time Space Pros Cons
Min-Heap O(n log k) O(k) Simple, intuitive Extra space for heap
Divide & Conquer O(n log k) O(log k) Optimal time, elegant Recursion overhead
Iterative Merge O(n log k) O(1) No recursion, optimal space More complex implementation

7. 💡 Summary

For the Merge k Sorted Lists problem:

  • Recommended Approach : Min-Heap is most intuitive and commonly used in interviews
  • Production Use : Divide and Conquer offers better space efficiency for large k
  • Key Insight: The problem can be reduced to repeatedly finding the minimum element or merging in a balanced way

The min-heap approach is particularly elegant because it abstracts away the complexity of comparing across multiple lists and always gives us the next smallest element efficiently.

Merging multiple sorted lists teaches us that complex coordination problems can often be solved by systematically identifying and processing the most promising next step - much like using a priority queue to always work on the most urgent task first.

相关推荐
我还可以再学点2 小时前
八股文面试攻略四:网络篇
网络·面试·职场和发展
王中阳Go2 小时前
面试被挂的第3次,面试官说:你懂的LLM框架,只够骗骗自己
面试·职场和发展
ANYOLY3 小时前
Sentinel 限流算法详解
算法·sentinel
No0d1es4 小时前
电子学会青少年软件编程(C/C++)六级等级考试真题试卷(2025年9月)
c语言·c++·算法·青少年编程·图形化编程·六级
AndrewHZ4 小时前
【图像处理基石】图像去雾算法入门(2025年版)
图像处理·人工智能·python·算法·transformer·cv·图像去雾
Knox_Lai4 小时前
数据结构与算法学习(0)-常见数据结构和算法
c语言·数据结构·学习·算法
川西胖墩墩4 小时前
流程图在算法设计中的实战应用
数据库·论文阅读·人工智能·职场和发展·流程图
橘颂TA5 小时前
【剑斩OFFER】算法的暴力美学——矩阵区域和
算法·c/c++·结构与算法
不会c嘎嘎5 小时前
每日一练 -- day1
c++·算法
hansang_IR5 小时前
【记录】网络流最小割建模三题
c++·算法·网络流·最小割