昨天面试被问到这道算法题,一时没有回答上来,今天思考了一下,参阅了网上的教程,做了一个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;
}
}

算法题:合并N个长度为L的有序数组为一个有序数组(JAVA实现)的更多相关文章

  1. [PHP] 算法-合并两个有序链表为一个有序链表的PHP实现

    合并两个有序的链表为一个有序的链表: 类似归并排序中合并两个数组的部分 1.遍历链表1和链表2,比较链表1和2中的元素大小 2.如果链表1结点大于链表2的结点,该结点放入第三方链表 3.链表1往下走一 ...

  2. 常见面试算法题JS实现-仅用递归函数和栈操作逆序一个栈

    前言: 因为JAVA和JS语言特性的不同,有些东西在JAVA中可能需要一些技巧和手段才能实现的复杂程序,但是在JS中可能就是天然存在的,所以这套书里面的题目不会全部用JS去实现一遍,因为可能JS的实现 ...

  3. JS-常考算法题解析

    常考算法题解析 这一章节依托于上一章节的内容,毕竟了解了数据结构我们才能写出更好的算法. 对于大部分公司的面试来说,排序的内容已经足以应付了,由此为了更好的符合大众需求,排序的内容是最多的.当然如果你 ...

  4. Good Vegetable 4级算法题 分值: [320/3120] 问题: [8/78]

    1523 非回文 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 一个字符串是非回文的,当且仅当,他只由前p个小写字母 ...

  5. 「面试高频」二叉搜索树&双指针&贪心 算法题指北

    本文将覆盖 「字符串处理」 + 「动态规划」 方面的面试算法题,文中我将给出: 面试中的题目 解题的思路 特定问题的技巧和注意事项 考察的知识点及其概念 详细的代码和解析 开始之前,我们先看下会有哪些 ...

  6. 51nod图论题解(4级,5级算法题)

    51nod图论题解(4级,5级算法题) 1805 小树 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 她发现她的树的点上都有一个标号(从1到n),这些树都在空 ...

  7. 算法:合并排序(Merge Sort)

    算法定义 合并排序是一种递归算法,思路如下: 如果源数组长度为 1,立即返回. 将源数组平分为两个新数组:Left 和 Right. 对 Left 执行递归排序. 对 Right 执行递归排序. 将排 ...

  8. 小小c#算法题 - 8 - 归并排序 (Merging Sort)

    “归并”的含义是将两个或两个以上的有序序列组合成一个新的有序序列.这个“归并”可以在O(n+m)的数量级上实现,但这同时也需要O(n+m)的空间复杂度.具体为:首先分配一个新的长度为n+m的空序列,然 ...

  9. python每日经典算法题5(基础题)+1(较难题)

    一:基础算法题5道 1.阿姆斯特朗数 如果一个n位正整数等于其各位数字的n次方之和,则称该数为阿姆斯特朗数.判断用户输入的数字是否为阿姆斯特朗数. (1)题目分析:这里要先得到该数是多少位的,然后再把 ...

随机推荐

  1. SQL Server中如何定位Row Lock锁定哪一行数据

    在SQL Server中有时候会使用提示(Hint)强制SQL使用行锁(Row Lock),前两天有个同事咨询了一个问题,如何定位Row Lock具体锁定了哪一行.其实这个问题只适合研究一下,实际意义 ...

  2. django CharField按整形排序

    #models.py from django.db import models class Block(models.Model): ... height = models.CharField(max ...

  3. C#判断文件编码——常用字法

    使用中文写文章,当篇幅超过一定程度,必然会使用到诸如:“的”.“你”.“我”这样的常用字.本类思想便是提取中文最常用的一百个字,使用中文世界常用编码(主要有GBK.GB2312.GB18030.UTF ...

  4. SQL Server Browser探究

    一.官网关于SQL SERVER Browser服务的解释(谷歌翻译后稍作修改的): https://docs.microsoft.com/en-us/sql/tools/configuration- ...

  5. 记一次 MySQL semaphore crash 的分析(爱可生)

    文章来源:爱可生云数据库作者:洪斌 DBA应该对InnoDB: Semaphore wait has lasted > 600 seconds. We intentionally crash t ...

  6. linux 查看命令 ls-list

    1. ls 基础常用 显示指定目录下的文件列表 list ls -lthr /floder l    长的列表格式 lang 能查看到常用大部分信息 t    按时间先后排序 (sort排序) tim ...

  7. python——函数之装饰器

    1 问题 实际生活中,我们很难一次性就把一个函数代码写得完美无缺.当我们需要对以前的函数添加新功能时,我们应该怎么做? 2 问题解决思路 (1)可以直接修改原来的函数,在函数内直接修改.当我们对多个函 ...

  8. 《Java大学教程》--第1章 步入Java世界

    1.2 软件:用于计算机执行的指令的集合称之为程序(program).单个程序或者一组程序称之为软件(software)1.3 编译:计算机的语言称为机器码(machine code).用编译器(co ...

  9. 第一次使用Open Live Writer维护BlogJava

    换了电脑,又重装了一堆东西,现在才把Open Live Writer整好.顺便记下几个心得: Open Live Writer已经没办法从网站上下载了,介绍个方法,可以把地址直接拷贝到迅雷里面,然后请 ...

  10. 引用变量 php面试总结1

    (1)PHP引用变量 概念:不同的变量名,访问同一个变量内容,使用& 知识点: 使用php函数 (a)memory_get_usage() 查看内存使用情况 eg // 定义一个变量 $a = ...