Bootstrap

k个有序序列的合并,用小根堆解决

LeetCode第23题,这里如果会了,堆排序包括常见的对链表的处理肯定没问题了。

/**
 * 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[] lists1) {

        //有空的ListNode,都先去掉
        ListNode[] lists = new ListNode[lists1.length];
        int j = 0;
        for(int i= 0 ;i<lists1.length;i++){
            if(lists1[i] == null){
                continue;
            }
            lists[j++] = lists1[i];
        }

        if(j == 0){
            return null;
        }

        //用小根堆思路求解
        buildLittleHeap(lists,j);
        ListNode result = new ListNode(0); //注意,result链表的第一个节点是为了方便处理加的根节点,后续须返回next
        ListNode resultTemp = result; 
        int size = j;
        while(size>0 && lists[0] !=null){
            resultTemp.next = new ListNode(lists[0].val);
            resultTemp = resultTemp.next;
            lists[0] = lists[0].next;
            if(lists[0] == null){
                //这里如果size=1,则lists[0]自己跟自己换,等于没换,还是null
                swap(lists,0,size-1);
                size--;
                adjust(lists,0,size);
            }else{
                adjust(lists,0,size);
            }
        }
        return result.next;
    }

    public void buildLittleHeap(ListNode[] arr,int size){
        for(int i = size/2 - 1;i >= 0;i--){
            adjust(arr,i,size);
        }
    }
    
    public void adjust(ListNode[] arr,int k,int size){
        for(int i = 2*k+1;i<size;k=i,i=2*k+1){
            if(i+1 < size && arr[i].val > arr[i+1].val){
                i++;
            }
            if(arr[k].val <= arr[i].val){
                break;
            }
            swap(arr,i,k);
        }
    }

    public void swap(ListNode[] arr,int i,int j){
        ListNode tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    } 

}
;