• k路归并:数组、链表


    /**
     * 解法1:逐个合并数组,时间复杂度O(n*k),n >> k
     * 合并k个排序(升序)数组
     * http://www.lintcode.com/zh-cn/problem/merge-k-sorted-arrays/
     * @author yzwall
     */
    class Solution {
        public List<Integer> mergekSortedArrays(int[][] arrays) {
            ArrayList<Integer> list = new ArrayList<Integer>();
            if (arrays == null || arrays.length == 0 || arrays[0].length == 0) {
                return list;
            }
            if (arrays.length == 1) {
                Arrays.sort(arrays[0]);
                for (int num : arrays[0]) {
                    list.add(num);
                }
                return list;
            }
            
            int[] temp = mergeTwoArrays(arrays[0], arrays[1]);
            for (int i = 2; i < arrays.length; i++) {
                temp = mergeTwoArrays(temp, arrays[i]);
            }
            for (int num : temp) {
                list.add(num);
            }
            return list;
        }
        
        private int[] mergeTwoArrays(int[] A, int[] B) {
            if (A.length == 0 || B.length == 0) {
                return new int[0];
            }
            int[] temp = new int[A.length + B.length];
            int index = 0, i = 0, j = 0;
            while (i < A.length && j < B.length) {
                if (A[i] < B[j]) {
                    temp[index++] = A[i++];
                } else {
                    temp[index++] = B[j++];
                }
            }
            while (i < A.length) {
                temp[index++] = A[i++];
            }
            while (j < B.length) {
                temp[index++] = B[j++];
            }
            return temp;
        }
    }
    
    /**
     * 解法2:分治法K路归并,时间复杂度O(n logk)
     * 合并k个排序(升序)数组
     * http://www.lintcode.com/zh-cn/problem/merge-k-sorted-arrays/
     * @author yzwall
     */    
    class Solution20 {
        public List<Integer> mergekSortedArrays(int[][] arrays) {
            ArrayList<Integer> list = new ArrayList<Integer>();
            if (arrays == null || arrays.length == 0 || arrays[0].length == 0) {
                return list;
            }
            int[] ans = kMergeSort(arrays, 0, arrays.length - 1);
            for (int num : ans) {
                list.add(num);
            }
            return list;
        }
        
        // 分治递归深度为O(log k), 每层合并时间复杂度O(n)
        private int[] kMergeSort(int[][] arrays, int start, int end) {
            if (start >= end) {
                return arrays[start];
            }
            int mid = start + (end - start) / 2;
            int[] left = kMergeSort(arrays, start, mid);
            int[] right = kMergeSort(arrays, mid + 1, end);
            return mergeTwoArrays(left, right);
        }
        
        private int[] mergeTwoArrays(int[] A, int[] B) {
            int[] temp = new int[A.length + B.length];
            int index = 0, i = 0, j = 0;
            while (i < A.length && j < B.length) {
                if (A[i] < B[j]) {
                    temp[index++] = A[i++];
                } else {
                    temp[index++] = B[j++];
                }
            }
            while (i < A.length) {
                temp[index++] = A[i++];
            }
            while (j < B.length) {
                temp[index++] = B[j++];
            }
            return temp;
        }
    }
    
    /**
     * 解法3:最小堆实现K路归并,时间复杂度O(n logk)
     * 合并k个排序(升序)数组
     * http://www.lintcode.com/zh-cn/problem/merge-k-sorted-arrays/
     * @author yzwall
     */
    class Solution18 {
        private class NewInteger {
            int value, row, col;
            public NewInteger(int value, int row, int col) {
                this.value = value;
                this.row = row;
                this.col = col;
            }
        }
        
        public List<Integer> mergekSortedArrays(int[][] arrays) {
            ArrayList<Integer> list = new ArrayList<Integer>();
            if (arrays == null || arrays.length == 0 || arrays[0].length == 0) {
                return list;
            }
            PriorityQueue<NewInteger> pq = new PriorityQueue<>(arrays.length, new Comparator<NewInteger>() {
                public int compare(NewInteger o1, NewInteger o2) {
                    return o1.value < o2.value ? -1 : 1;
                }
            });
            
            for (int i = 0; i < arrays.length; i++) {
                pq.offer(new NewInteger(arrays[i][0], i, 0));
            }
            while (!pq.isEmpty()) {
                NewInteger min = pq.poll();
                if (min.col + 1 < arrays[min.row].length) {
                    pq.offer(new NewInteger(arrays[min.row][min.col + 1], min.row, min.col + 1));
                }
                list.add(min.value);
            }
            
            return list;
        }
    }
    
    /**
     * 解法4:暴力方法,将所有数组添加到List,统一排序,时间复杂度O(n*k + nlogn), n >> k
     * 合并k个排序(升序)数组
     * http://www.lintcode.com/zh-cn/problem/merge-k-sorted-arrays/
     * @author yzwall
     */
    class Solution19 {
        public List<Integer> mergekSortedArrays(int[][] arrays) {
            ArrayList<Integer> list = new ArrayList<Integer>();
            if (arrays == null || arrays.length == 0 || arrays[0].length == 0) {
                return list;
            }
            for (int i = 0; i < arrays.length; i++) {
                addToList(list, arrays[i]);
            }
            Collections.sort(list);
            return list;
        }
        
        private void addToList(ArrayList<Integer>list, int[] nums) {
            for (int num : nums) {
                list.add(num);
            }
        }
    }
    

      

    上面的代码转载自:K路归并问题小结

    在LeetCode 23中是合并k路链表

    23. Merge k Sorted Lists

    自己的代码如下,采用的是优先级队列

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        private class MinHeapComparator implements Comparator<ListNode>{
            public int compare(ListNode node1, ListNode node2){
                return node1.val - node2.val;
            }
        }
        
        public ListNode mergeKLists(ListNode[] lists) {
            ListNode res = new ListNode(0);
            if(lists.length <= 0) return null;
            if(lists.length == 1) return lists[0];
            PriorityQueue<ListNode> queue = new PriorityQueue<>(new MinHeapComparator());
            for(int i = 0; i < lists.length; i++){
                if(lists[i] != null)
                    queue.offer(lists[i]);
            }
            ListNode node = res;
            while(!queue.isEmpty()){
                ListNode littleNode = queue.poll();
                node.next = littleNode;
                node = node.next;
                if(littleNode.next != null)
                    queue.offer(littleNode.next);
            }
            return res.next;
        }
    }
    

      

  • 相关阅读:
    关键词提取算法TextRank
    我的博文目录整理
    Windows Azure一些小技巧集合
    js数组和树互转
    this.props.form.validateFields回调不执行问题
    d3的4.x与3.x版本的区别
    d3提示框,虚线,选择区域
    d3布局
    d3文件导入和导出
    d3交互
  • 原文地址:https://www.cnblogs.com/SkyeAngel/p/9394037.html
Copyright © 2020-2023  润新知