这是悦乐书的第161次更新,第163篇原创

01 看题和准备

今天介绍的是LeetCode算法题中Easy级别的第20题(顺位题号是88)。给定两个排序的整数数组nums1和nums2,将nums2中的元素合并到nums1中,并且作为一个排序的数组。在nums1和nums2中初始化的元素个数分别为m和n。假设nums1有足够的空间(大于或等于m + n)来保存nums2中的其他元素。例如:

输入:nums1 = [1,2,3,0,0,0],m = 3,nums2 = [2,5,6],n = 3

输出:[1,2,2,3,5,6]

本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试。

02 第一种解法

给的条件很清晰,nums1的长度大于等于m+n的和,nums2的元素是肯定可以全部放进nums1的,既如此,那我们是不是可以先把nums2中的元素添加进nums1,从下标m开始,移入n个新的元素,然后再对nums1进行排序,最后得到新的nums1数组。排序算法使用了冒泡排序,当然使用其他的排序算法也是可以的。

public void merge(int[] nums1, int m, int[] nums2, int n) {
for (int i=m, k=0; i<nums1.length && k < n ; i++,k++) {
nums1[i] = nums2[k];
}
for (int j=0; j<nums1.length-1; j++) {
for (int h=0; h<nums1.length-1-j; h++) {
if (nums1[h] > nums1[h+1]) {
int temp = nums1[h+1];
nums1[h+1] = nums1[h];
nums1[h] = temp;
}
}
}
}

03 第二种解法

上面的解法的时间复杂度是O(n^2),那能不能再降低点?让其更快一点?让我们来借助例子分析下。

nums1 = [1,2,3,0,0,0],m = 3

nums2 = [2,5,6],n = 3

既然最后结果是将新的nums1排序,那么按照升序来排,两个数组中最大的一个值肯定在第m+n位。

第一步,分别获取nums1的第3位元素、nums2的第3位元素,比较两数大小,数值大的放在nums1的第6位,此时nums1变成了[1,2,3,0,0,6]。

第二步,分别获取nums1的第3位元素、nums2的第2位元素,比较两数大小,数值大的放在nums1的第5位,此时nums1变成了[1,2,3,0,5,6]。因为第一步是将nums2的元素移到了nums1,所以nums2向前移动一位,但是nums1的第3位并没有完全确定大小,所以保持不动。

第三步,分别获取nums1的第3位元素、nums2的第1位元素,比较两数大小,数值大的放在nums1的第4位,此时nums1变成了[1,2,3,3,5,6]。

第四步,分别获取nums1的第2位元素、nums2的第1位元素,比较两数大小,数值大的放在nums1的第3位,此时nums1变成了[1,2,2,3,5,6]。

依据上面的步骤,可以很快的写出代码,但是有种特殊情况要考虑,当nums1的最小值,也就是nums1的第一位元素,它比nums2的最大值都大的时候,nums2的元素是要全部移到nums1原元素的前面,此时在循环完后,就要加多一个判断,判断nums2的元素下标是否已经移动到了第一位。

public void merge2(int[] nums1, int m, int[] nums2, int n) {
int i = m - 1;
int j = n - 1;
while (i >= 0 && j >= 0) {
if (nums1[i] > nums2[j]) {
nums1[i + j + 1] = nums1[i];
i--;
} else {
nums1[i + j + 1] = nums2[j];
j--;
}
}
while (j >= 0) {
nums1[i + j + 1] = nums2[j];
j--;
}
}

04 验证与测试

为了验证上面两种解法的正确性和效率,我们使用了一些数据来测试。

public static void main(String[] args) {
Easy_088_MergeSortedArray instance = new Easy_088_MergeSortedArray();
int[] nums1 = {1,2,2,3,4,5,0,0,0};
int m = 6;
int[] nums2 = {2,5,8};
int n = 3; long start = System.nanoTime();
instance.merge(nums1, m, nums2, n);
long end = System.nanoTime();
System.out.println("merge---输出:"+Arrays.toString(nums1)+" , 用时:"+(end-start)/1000+"微秒"); int[] nums3 = {1,2,2,3,4,5,0,0,0};
int m2 = 6;
int[] nums4 = {2,5,8};
int n2 = 3;
long start2 = System.nanoTime();
instance.merge2(nums3, m2, nums4, n2);
long end2 = System.nanoTime();
System.out.println("merge2---输出:"+Arrays.toString(nums1)+" , 用时:"+(end2-start2)/1000+"微秒");
}

测试结果如下

merge---输出:[1, 2, 2, 2, 3, 4, 5, 5, 8] , 用时:4微秒
merge2---输出:[1, 2, 2, 2, 3, 4, 5, 5, 8] , 用时:2微秒

从运行时间来看,解法二是明显优于解法一的,解法二的时间复杂度是O(n)。

05 小结

可能有人会想到借助Arrays.sort()方法来排序,但是如果是面试的时候,还是使用解法二好些。

以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!

LeetCode算法题-Merge Sorted Array(Java实现)的更多相关文章

  1. LeetCode算法题-Convert Sorted Array to Binary Search Tree(Java实现)

    这是悦乐书的第166次更新,第168篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第25题(顺位题号是108).给定一个数组,其中元素按升序排序,将其转换为高度平衡的二叉 ...

  2. LeetCode算法题-Merge Two Binary Trees(Java实现)

    这是悦乐书的第274次更新,第290篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第142题(顺位题号是617).提供两个二叉树,将其合并为新的二叉树,也可以在其中一个二 ...

  3. 【算法】LeetCode算法题-Merge Two Sorted List

    这是悦乐书的第148次更新,第150篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第7题(顺位题号是21).合并两个已排序的链表并将其作为新链表返回. 新链表应该通过拼接 ...

  4. 【LeetCode练习题】Merge Sorted Array

    Merge Sorted Array Given two sorted integer arrays A and B, merge B into A as one sorted array. Note ...

  5. LeetCode算法题-Rotate String(Java实现)

    这是悦乐书的第317次更新,第338篇原创 在开始今天的算法题前,说几句,今天是世界读书日,推荐两本书给大家,<终身成长>和<禅与摩托车维修艺术>,值得好好阅读和反复阅读. 0 ...

  6. LeetCode算法题-Rotated Digits(Java实现)

    这是悦乐书的第316次更新,第337篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第185题(顺位题号是788).如果一个数字经过180度旋转后,变成了一个与原数字不同的 ...

  7. LeetCode算法题-Toeplitz Matrix(Java实现)

    这是悦乐书的第312次更新,第333篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第181题(顺位题号是766).如果从左上角到右下角的每个对角线具有相同的元素,则矩阵是 ...

  8. LeetCode算法题-Flood Fill(Java实现)

    这是悦乐书的第306次更新,第325篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第173题(顺位题号是733).图像由二维整数数组表示,每个整数表示图像的像素值(从0到 ...

  9. LeetCode算法题-Image Smoother(Java实现)

    这是悦乐书的第282次更新,第299篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第150题(顺位题号是661).给定表示图像灰度的2D整数矩阵M,您需要设计一个平滑器以 ...

随机推荐

  1. python安装Jieba中文分词组件并测试

    python安装Jieba中文分词组件 1.下载http://pypi.python.org/pypi/jieba/ 2.解压到解压到python目录下: 3.“win+R”进入cmd:依次输入如下代 ...

  2. Docker在Linux上运行NetCore系列(四)使用私有Nuget与多个本地包引用运行ASPNetCore

    转发请注明此文章作者与路径,请尊重原著,违者必究. 本篇文章演示了使用Dockerfile在Linux(ubuntu16.04)系统上构建ASPNetCore应用,并且在一个解决方案中存在多个项目之间 ...

  3. Jmter接口网站压力测试工具使用记录

    1.首先下载Jmeter 官方地址:http://jmeter.apache.org/ 2.安装Jmeter 把下载的文件进行解压,产生如下目录: 打开bin文件夹下的jmeter.bat文件及进入程 ...

  4. STM32-对芯片启动读保护,实现加密(详解)

    STM32可以对存储在flash上的程序进行读保护. 启动读保护后,用户就不能再读写程序了. 所以,在烧写程序之前,需要程序调用关闭读保护.关闭读保护后,会自动清空flash上的程序 头文件位于:#i ...

  5. Java 学习笔记 泛型

    泛型 上界匹配 ? extends Number 下界匹配 ? super Number getSimpleName 不包括包名 getName 会包括包名 常和反射联合使用,做框架 Type是一个标 ...

  6. Javascript 跨域知识详细介绍

    JS跨域知识总结: 在“跨域”一词经常性地出现以前,我们其实已经频繁地使用它了.如在A网站的img,src指向B网站的某一图片地址,毫无疑问,这在通常情况下都是能正常显示的(且不论防盗链技术):同样, ...

  7. Netty实现一个简单聊天系统(点对点及服务端推送)

    Netty是一个基于NIO,异步的,事件驱动的网络通信框架.由于使用Java提供 的NIO包中的API开发网络服务器代码量大,复杂,难保证稳定性.netty这类的网络框架应运而生.通过使用netty框 ...

  8. 【读书笔记】iOS-使用钥匙串保护数据

    一,将应用从设备上删除时,并不会删除其钥匙串项,这使得调试工作困难得多.模拟器有一个Reset Contents and Settings选项,可用于将钥匙串项移除.因此,强烈建议在模拟器上确定Key ...

  9. 深入浅出LSTM神经网络

    转自:https://www.csdn.net/article/2015-06-05/2824880 LSTM递归神经网络RNN长短期记忆   摘要:根据深度学习三大牛的介绍,LSTM网络已被证明比传 ...

  10. Salesforce 数据备份和恢复小知识

    数据备份的类型 在Salesforce中可以使用多种API进行数据备份,它们是: REST API SOAP API Buik API Metadata API 数据备份有三种选择: 完全备份(Ful ...