zoukankan      html  css  js  c++  java
  • 算法题:合并N个长度为L的有序数组为一个有序数组(JAVA实现)

    昨天面试被问到这道算法题,一时没有回答上来,今天思考了一下,参阅了网上的教程,做了一个JAVA版本的实现。

    方案一:

    新建一个N*L的数组,将原始数组拼接存放在这个大数组中,再调用Arrays.sort()进行排序,或者使用其它排序方法即可。

    此方法时间复杂度为o(N*Llog2N*L);

    具体代码实现如下:

    import java.util.Arrays;
    class Solution {
        public static int[] MergeArrays(int[][] array) {
            int N = array.length, L;
            if (N == 0)
                return new int[0];
            else {
                L = array[0].length;
                for (int i = 1; i < N; i++)
                    if (L != array[i].length)
                        return new int[0];
            }
            int[] result = new int[N * L];
            for (int i = 0; i < N; i++)
                for (int j = 0; j < L; j++)
                    result[i * L + j] = array[i][j];
            Arrays.sort(result);
            return result;
        }
    }

    方案二:

    使用PriorityQueue实现最小堆,需要定义一个指针数组,用于保存这N个数组的index,定义Node类用于保存当前数值(value)和该数字所在的数组序号(idx),并且覆写Comparetor<Node>的compare方法实现自定义排序。PriorityQueue的offer()和poll()方法时间复杂度均为logn。

    思路:首先将N个数组的第一位放到PriorityQueue,循环取出优先队列的首位(最小值)放入result数组中,并且插入该首位数字所在数组的下一个数字(如果存在),直到所有数字均被加入到result数组即停止(N*L)次。

    时间复杂度:O(N*LlogN)

    空间复杂度:O(N)

    代码实现:

    import java.util.PriorityQueue;
    import java.util.Arrays;
    import java.util.Comparator;
    
    public class SortedArraysMerge {
        static class Node {
            int value;
            int idx;
    
            public Node(int value, int idx) {
                this.value = value;
                this.idx = idx;
            }
        }
    
        public static int[] MergeArrays(int[][] arr) {
            int N = arr.length, L;
            if (N == 0)//此时传入数组为空
                return new int[0];
            else {//判断数组是否符合规范
                L = arr[0].length;
                for (int i = 1; i < N; i++)
                    if (arr[i].length != L)
                        return new int[0]; //此时数组不规范
            }
            int[] result = new int[N * L];
            int[] index = new int[N];
            Arrays.fill(index, 0, N, 0);
            PriorityQueue<Node> queue = new PriorityQueue<Node>(new Comparator<Node>() {
                @Override
                public int compare(Node n1, Node n2) {
                    if (n1.value < n2.value)
                        return -1;
                    else if (n1.value > n2.value)
                        return 1;
                    else
                        return 0;
                }
            });
            for (int i = 0; i < N; i++) {
                Node node = new Node(arr[i][index[i]++], i);
                queue.offer(node);
            }
            System.out.println("" + queue.size());
            int idx = 0;
            while (idx < N * L) {
                Node minNode = queue.poll();
                result[idx++] = minNode.value;
                if (index[minNode.idx] < L) {
                    queue.offer(new Node(arr[minNode.idx][index[minNode.idx]], minNode.idx));
                    index[minNode.idx]++;
                }
            }
            return result;
        }
    }
  • 相关阅读:
    jprofiler配置
    Nginx编译安装
    WebBench的安装与使用
    你经常看到却经常忽视的__init__.py有什么用?
    彻底搞懂Python 中的 import 与 from import
    实现有过期时间的LRU缓存
    实现函数调用结果的 LRU 缓存
    elasticsearch Routing 路由详解
    Elasticsearch _reindex 接口来重新索引数据到新索引,使用新的配置
    浏览器操作elasticsearch别名
  • 原文地址:https://www.cnblogs.com/guoyaohua/p/8618977.html
Copyright © 2011-2022 走看看