LeetCode算法题-Merge Sorted Array(Java实现)

这是悦乐书的第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()方法来排序,但是如果是面试的时候,还是使用解法二好些。

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

原文地址:https://www.cnblogs.com/xiaochuan94/p/9903071.html

时间: 2025-01-06 13:38:24

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

leetcode 题解:Merge Sorted Array(两个已排序数组归并)

题目: Given two sorted integer arrays A and B, merge B into A as one sorted array. Note:You may assume that A has enough space (size that is greater or equal to m + n) to hold additional elements from B. The number of elements initialized in A and B ar

LeetCode算法题-Single Number(Java实现)

这是悦乐书的第175次更新,第177篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第34题(顺位题号是136).给定一个非空的整数数组,除了一个元素外,每个元素都会出现两次. 找到那个只出现了一次的元素.例如: 输入:[2,2,1] 输出:1 输入:[4,1,2,1,2] 输出:4 本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试. 02 第一种解法 因为已经限定传入的数组不为空,所以此题不需要

LeetCode算法题-Min Stack(Java实现)

这是悦乐书的第177次更新,第179篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第36题(顺位题号是155).设计一个支持push,pop,top和在恒定时间内检索最小元素的堆栈. push(x) - 将元素x推入堆栈. pop() - 删除堆栈顶部的元素. top() - 获取顶部元素. getMin() - 检索堆栈中的最小元素. 例如: MinStack minStack = new MinStack(); minStack.push(-2); minSta

LeetCode算法题-Reverse Bits(Java实现)

这是悦乐书的第185次更新,第187篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第44题(顺位题号是190).给定32位无符号整数,求它的反转位.例如: 输入:43261596 输出:964176192 说明:43261596以二进制表示为00000010100101000001111010011100, 964176192以二进制表示为00111001011110000010100101000000. 本次解题使用的开发工具是eclipse,jdk使用的版本是1

LeetCode算法题-Move Zeroes(Java实现-三种解法)

这是悦乐书的第201次更新,第211篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第67题(顺位题号是283).给定一个数组nums,写一个函数将所有0移动到它的末尾,同时保持非零元素的相对顺序.例如: 输入:[0,1,0,3,12] 输出:[1,3,12,0,0] 注意: 您必须在不制作数组副本的情况下就地执行此操作. 最小化操作总数. 本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试. 02

LeetCode算法题-Word Pattern(Java实现)

这是悦乐书的第202次更新,第212篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第68题(顺位题号是290).给定一个模式和一个字符串str,找到str是否完全匹配该模式.完全匹配是指在模式中的字母和str中的非空单词之间存在一一对应的关系.例如: 输入:pattern ="abba",str ="dog cat cat dog" 输出:true 输入:pattern ="abba",str ="dog

LeetCode算法题-Binary Watch(Java实现)

这是悦乐书的第216次更新,第229篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第84题(顺位题号是401).二进制手表顶部有4个LED,代表小时(0-11),底部的6个LED代表分钟(0-59).每个LED代表一个零或一个,右侧的最低有效位.给定非负整数n表示当前打开的LED数量,返回手表可能代表的所有可能时间.例如: 输入:n = 1 输出:["1:00","2:00","4:00","8:00&qu

LeetCode算法题-Add Strings(Java实现)

这是悦乐书的第223次更新,第236篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第90题(顺位题号是415).给定两个非负整数num1和num2表示为字符串,返回num1和num2的总和. 注意: num1和num2的长度均<5100. num1和num2都只包含数字0-9. num1和num2都不包含任何前导零. 您不能使用任何内置BigInteger库或直接将输入转换为整数. 本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 6

LeetCode算法题-Arranging Coins(Java实现)

这是悦乐书的第229次更新,第241篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第96题(顺位题号是441).您想要以楼梯形状形成总共n个硬币,其中每个第k行必须具有恰好k个硬币.给定n,找到可以形成的完整楼梯行的总数.n是一个非负整数,适合32位有符号整数的范围.例如: n = 5 硬币可以形成以下行: ¤ ¤¤ ¤¤ 因为第3行不完整,我们返回2. n = 8 硬币可以形成以下行: ¤ ¤¤ ¤¤¤ ¤¤ 因为第4行不完整,我们返回3. 本次解题使用的开发工具