《LeetCode系列》---合并两个有序数组

今天的这道leetcode题,将通过逆向双指针来进行解决。

《LeetCode系列》---合并两个有序数组_第1张图片

 

涉及知识:

        数组相关知识的基础;


目录

一、题目描述

二、思路分析

1、题目思路

2、代码分析

 三、代码提交


一、题目描述

题目名称合并两个有序数组(编号88)

难度简单

《LeetCode系列》---合并两个有序数组_第2张图片《LeetCode系列》---合并两个有序数组_第3张图片

 简单来说,该题就是给了两个有序的数组nums1和nums2,然后将两个数组合并后存储在nums1里。


二、思路分析

1、题目思路

通过该题描述,合并后的数组是有序的。

这时有些聪明的人,也许就会想到把两个数组合并后再直接用库方法sort()来排序。

虽然可以直接解出该题,但不建议这么做。

这么做的话,这道题就没有意思了呀。

(1)该题中给的参数不止有两个数组,还有对应两个数组的长度(m和n)。那么我们可以通过该长度来获取数组的下标。

(2)定义两个数组的最后一个元素的下标位置,然后通过遍历,从每一个数组的最后一个下标位置开始进行比较。(从后面开始确定)

(3)由于两个数组合并后要存储在第一个数组nums1里面,那么我们何不将比较好后较大的一个元素,直接存储在nums1的最后一个下标位置(nums1的长度得进行扩容)。

(4)那么我们就需要有三个位置的指针,分别是第一个数组nums1的m-1位置,第二数组nums2的n-1位置和要增添进第一个数组nums1末尾的m+n-1位置。

  • 为什么都要减1?

因为数组是从下标0位置开始,m和n,m+n都是作为数组的长度,需要减1才能获取最后一个下标位置。

  • m+n是代表什么?

因为要合并两个数组,并存储进第一个数组里面,那么存储后的第一个数组nums1,其长度不得变成两个数组长度之和(m+n)。


2、代码分析

代码示例:

public class TestDemo1 {
    public static void merge(int[] nums1, int m, int[] nums2, int n){
        int i=m-1;       //nums1数组的末位置
        int j=n-1;       //nums2数组的末位置
        int k=m+n-1;     //合并后nums1数组的末尾置
        while(i>=0&&j>=0){
            //从末尾开始比较,直到其中一个数组下标位置为0
            if(nums1[i]>=nums2[j]){
            //如果数组1的i位置元素大于或等于数组2的j位置元素,就将大的一方存储在k的位置
                nums1[k]=nums1[i];
                i--;        //之后要将i和k向左移动
                k--;
            } else{
            //如果数组2的j位置元素大于或等于数组1的i位置元素,就将大的一方存储在k的位置
                nums1[k]=nums2[j];
                j--;        //之后要将j和k向左移动
                k--;
            }
        }
        //当然有可能存在其中一个数组的长度小于另外一个
        //这时就会出现其中一个数组已经遍历完,但另外一个数组却没有
        //那么我们就要将还没遍历完的数组直接存储在k的下一个位置里,直到这个数组也遍历完
        while(i>=0){
            nums1[k]=nums1[i];
            i--;
            k--;
        }
        while(j>=0){
            nums1[k]=nums2[j];
            j--;
            k--;
        }
        //一切遍历完后,就完成了合并的过程
    }
    public static void main(String[] args) {
    //假设两个数组的长度都是3
        int []arr1={1,2,3,0,0,0};
        int []arr2={4,5,6};
        int m=3,n=3;
        merge(arr1,m,arr2,n);    //调用合并方法
        System.out.println(Arrays.toString(arr1));    //将数组转换成字符串再打印出来
    }
}

(1)这道题利用逆向双指针来解决,那么此处我们得定义三个位置的指针。

(2)为了对这两个数组中的每一个元素进行比较 ,因为是从末位置开始往前循环比较,那么当定义的数组长度i或j小于0时,即说明这个数组已经都存储进nums1里了。 

《LeetCode系列》---合并两个有序数组_第4张图片


 

以下面这个图为例,比较完后,j小于0,nums2里的4、5、6都存进绿色方框位置,此时合并有序数组就完成了。

《LeetCode系列》---合并两个有序数组_第5张图片

(3)

可有一种情况是,如果其中一个数组的长度小于另外一个数组长度,那么就会出现长度小的数组已经存进去了,但大的数组还没进行排序存进去。   

还有一种情况是nums2的数组元素都小于nums1的数组元素,那么当nums1遍历完后循环结束,nums2的元素还没存进nums1里去.     

《LeetCode系列》---合并两个有序数组_第6张图片

因此我们得对这两种情况进行处理。

对两个数组进行一次遍历判断。

如果下标位置还是大于或等于0,说明还没有完全存储进数组1,那么只需继续存进对应nums1的k位置,再更新k和对应数组的下标i或j即可。 

《LeetCode系列》---合并两个有序数组_第7张图片

 

【注意】:

        这种方法只能应用于两个“有序”数组 ,前提条件是有序,如果是两个非有序数组,是不可以用以上这种方法进行合并的.

 三、代码提交

《LeetCode系列》---合并两个有序数组_第8张图片

《LeetCode系列》---合并两个有序数组_第9张图片

你可能感兴趣的:(LeetCode,java,后端,leetcode)