Leetcode 23. Merge k Sorted Lists [hard][java][in fact, it may be medium]

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

Example
在这里插入图片描述

Solution 1: Brute Force
Consideration

  1. we use a pre pointer to point to the current node that would add next node
  2. We compare the current merged node with the new list node
  3. If the new list node is smaller, we need to let the new list node to be the next of the current node. And repeat the comparison.
  4. After the comparison, if the new list node is not empty, add it to the end of the merged node list.

Time Complexity:O(kn) where k is the length of lists and N is the longest length of any list node, Space complexity: O(kn)

class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists.length == 0)
            return null;
        
        ListNode dummy = new ListNode(0);
        dummy.next = lists[0];
        
        for(int i = 1; i < lists.length; i++) {
            ListNode temp = lists[i];
            ListNode pre = dummy;
            ListNode merged = dummy.next;
            while(merged!=null && temp != null) {
                if(temp.val < merged.val) {
                    pre.next = temp;
                    temp = temp.next;
                    pre.next.next = merged;
                    pre = pre.next;
                } else {
                    pre = merged;
                    merged = merged.next;
                }
            }
            
            if(temp!=null)
                pre.next = temp; 
        }
        
        return dummy.next;
        
    }
}

Solution 2: Brute Force 2
Consideration

  1. we use a integer list to store all value nodes in the node list
  2. we then use sort function to sort the integer list
  3. finally, we add all values to the list node
    Time complexity
    在这里插入图片描述
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists.length == 0)
            return null;
        
        ListNode dummy = new ListNode(0);
        ListNode head = dummy;
        List<Integer> all = new ArrayList();
        
        for(int i = 0; i < lists.length; i++) {
            ListNode node = lists[i];
            while(node != null) {
                all.add(node.val);
                node = node.next;
            } 
        }
        Collections.sort(all);
        for(int i : all) {
            head.next = new ListNode(i);
            head = head.next;
        }
        
        return dummy.next;
        
    }
}

Solution 3: Compare every k node and get the minimal one
在这里插入图片描述

class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists.length == 0)
            return null;
        
        ListNode dummy = new ListNode(0);
        ListNode head = dummy;
        
        while(true) {
            boolean breakFlag = true;
            int min = Integer.MAX_VALUE;
            int min_index = -1;
            for(int i = 0; i < lists.length; i++) {
                if(lists[i] != null) {
                    if(lists[i].val < min) {
                        min = lists[i].val;
                        min_index = i;
                    }
                    breakFlag = false;
                }
            }
            if(breakFlag)
                break;
            head.next = lists[min_index];
            head = head.next;
            lists[min_index] = lists[min_index].next;
        } 
        
        return dummy.next;
        
    }
}

Solution 4: Optimize Approach 3 by Priority Queue
Consideration

  1. We create a priority queue (FIFO) to store the k min values of the list nodes
  2. Each time, we add the min one to the merged list and add the next of the min one to the priority queue

在这里插入图片描述

class Solution {
    
    public ListNode mergeKLists(ListNode[] lists) {
        
        Comparator<ListNode> cmp;
        cmp = new Comparator<ListNode>() {
            @Override
            public int compare(ListNode node1, ListNode node2) {
                // TODO Auto-generated method stub
                return node1.val-node2.val;
            }
        };
        
        //create the queue
        Queue<ListNode> que = new PriorityQueue(cmp);
        for(ListNode o:lists){
            if(o!=null)
                que.add(o);
        }
        
        ListNode dummy = new ListNode(0);
        ListNode head = dummy;
        
        while(!que.isEmpty()) {
            head.next = que.poll();
            head = head.next;
            ListNode next = head.next;
            if(next!=null) {
                que.add(next);
            }
        }
        
        return dummy.next;
        
    }
}

Solution 5: Merge lists one by one
In fact, this solution is the same as solution 1
Consideration

  1. Convert merge k lists problem to merge 2 lists (k-1) times.

在这里插入图片描述

class Solution {    
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists.length==0)
            return null;
        if(lists.length==1)
            return lists[0];
        
    
        ListNode head = mergeTwo(lists[0], lists[1]);        
        for(int i = 2; i < lists.length; i++)
            head = mergeTwo(head, lists[i]);
        
        return head;
        
    }
    
    private ListNode mergeTwo(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode head = dummy;
        while(l1!=null && l2!=null) {
            if(l1.val <= l2.val) {
                head.next = l1;
                l1 = l1.next;
            } else {
                head.next = l2;
                l2 = l2.next;
            }
            head = head.next;
        }
        
        if(l1!=null)
            head.next = l1;
        if(l2!=null)
            head.next = l2;
        return dummy.next;
    }
}

Solution 6: Merge with Divide And Conquer
Consideration

  1. We can improve solution 5 by merge pairs
  2. Each time we merge each pair lists of the node lists until the merged list is only one.

在这里插入图片描述

class Solution {    
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists.length==0)
            return null;
        int interval = 1;
        while(interval < lists.length) {
            for(int i = 0; i+interval < lists.length; i+= 2*interval) {
                lists[i] = mergeTwo(lists[i], lists[i+interval]);
            }
            interval*=2;
        }
        
        return lists[0];
        
    }
    
    private ListNode mergeTwo(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode head = dummy;
        while(l1!=null && l2!=null) {
            if(l1.val <= l2.val) {
                head.next = l1;
                l1 = l1.next;
            } else {
                head.next = l2;
                l2 = l2.next;
            }
            head = head.next;
        }
        
        if(l1!=null)
            head.next = l1;
        if(l2!=null)
            head.next = l2;
        return dummy.next;
    }
}

References

  1. https://leetcode.com/problems/merge-k-sorted-lists/solution/
  2. https://leetcode.wang/leetCode-23-Merge-k-Sorted-Lists.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值