NC51 merges k sorted linked lists

Posted by PJSheltrum on Sat, 05 Feb 2022 12:07:20 +0100

NC51 merges k sorted linked lists

Solution 1: use auxiliary array

  • Traverse each linked list and push the val value of the node into the array arr

  • Sort arr

  • Convert the sorted array into a linked list

  • Return header node head

  • Time complexity: traverse all nodes O(n), sort O(nlogn)

  • Space complexity: use an array with the same length as the number of nodes, O(n)

    /*
     * function ListNode(x){
     *   this.val = x;
     *   this.next = null;
     * }
     */
    
    /**
     * 
     * @param lists ListNode Class one-dimensional array 
     * @return ListNode class
     */
    function mergeKLists( lists ) {
        let arr = []
        for(let i = 0 ; i < lists.length ; i++){
            let p = lists[i]
            while( p != null){
                arr.push(p.val)
                p = p.next
            }
        }
        arr.sort( (a , b) => a-b )
        function ListNode(x){
            this.val = x;
            this.next = null;
        }
        let head = null
        let rear = null
        for(let j = 0 ; j < arr.length ; j ++){
            let node = new ListNode(arr[j])
            if(head == null){
                head = node
                rear = node
            }else{
                rear.next = node
                rear = node
            }
        }
        return head
    }
    module.exports = {
        mergeKLists : mergeKLists
    };
    

After reading the problem solution, I learned the following priority queue method. The three points of others' problem solution are simple, and I have many practical bug s. Here is my final idea and js code

Solution 2:

  • The priority queue is used to store the linked list. It is stored from small to large according to the value of the chain header node, and the smallest is at the top

    • Since lists are out of order, all need to be sorted. The sort method is used here
    • There may be empty linked lists. You need to delete the empty linked list before sorting. Here we use the split method
  • 1. Take out the queue head linked list, insert the chain header node into the target linked list head, and delete the chain header node

  • 2. Put the linked list back to the queue. If it is null, it will not be put back

    • When inserting a linked list, use binary search to find the position of the first node val greater than or equal to the chain header node, and then insert. When lists is empty and the font header node is greater than the header node of the last linked list, make a special judgment. You can directly push into lists. In other cases, use binary search
  • Repeat the above two steps until the queue is empty

  • Time complexity: for each node, the insertion cost is logk, k is the number of linked lists, and each node needs to be inserted and deleted. The total time complexity is nlogk, and N is the number of nodes

  • Space complexity: On

    /*
     * function ListNode(x){
     *   this.val = x;
     *   this.next = null;
     * }
     */
    
    /**
     * 
     * @param lists ListNode Class one-dimensional array 
     * @return ListNode class
     */
    function mergeKLists( lists ) {
        for(let i = 0 ; i < lists.length ; i++){
            if( !lists[i] ){
                lists.splice(i , 1)
                i --
            }
        }
        
        lists.sort((a, b) => (a.val - b.val))
        let head = null
        let rear = null
        while( lists.length != 0){
            let font = lists.shift()
            let node = font
            font = font.next
            console.log( 'node:',node.val)
            if(head == null){
                head = node
                rear = node
            }else{
                rear.next = node
                rear = node
            }
            if(font != null){
                if(lists.length == 0){
                    lists.push(font)
                }else if(font.val > lists[lists.length - 1].val){
                    lists.push(font)
                }else{
                    let index = 0
                    let left = 0
                    let right = lists.length - 1
                    while(left <= right){
                        let mid = Math.floor( (left + right) /2)
                        if(lists[mid].val < font.val){
                            left = mid + 1
                        }else{
                            right = mid - 1
                        }
                    }
                    index = left
                    console.log('index:' ,index)
                    lists.splice(index , 0 , font)
                }
                
            }
        }
        return head
    }
    module.exports = {
        mergeKLists : mergeKLists
    };
    

Topics: Algorithm data structure linked list