zoukankan      html  css  js  c++  java
  • 合并两个有序数组

    题目来源:

      力扣(LeetCode)

    题目名称:

      合并两个有序数组

    题目详情:

      给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组

    说明:

      初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。
      你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。

    示例:

      输入:
        nums1 = [1,8,9,15,0,0,0,0,0], m = 4
        nums2 = [2,5,6,12,18], n = 5

      输出: 

        [1,2,5,6,8,9,12,15,18]


    解法一:

    class Solution {
        public void merge(int[] nums1, int m, int[] nums2, int n) {
            int[] result = new int[m+n];      // 创建一个大小为m+n的数组,确保装的下所有排序的元素
            int i = 0;
            int j = 0;
            int k = 0;
            while(i < m && j < n){          // 从左往右,往result中装数据
                if(nums1[i] <= nums2[j]){
                    result[k++] = nums1[i++];
                }else{
                    result[k++] = nums2[j++];
                }
            }
            while(i < m){            // 将nums1中剩余元素加到result后面
                result[k++] = nums1[i++];
            }
            while(j < n){            // 将nums2中剩余元素加到result后面
                result[k++] = nums2[j++];
            }
            for(int s = 0; s < result.length; s++){  // 将排好序的result拷贝给nums1
                nums1[s] = result[s];
            }
        }
    }

      这种解法很简单,也很容易理解。就是额外创建一个数组result,数组的大小为m + n即所有排序元素的个数,用来往里面从左到右、从小到大装数据。创建三个指针,i 指向数组nums1的第一个元素,j 指向数组nums2的第一个元素,k 指向数组result的第一个位置。

      比较nums1和nums2的指针所指向的当前元素的大小,小的填入到result中 k 指向的位置,此时两个指针都向前移动一位,重复当前操作——填数据。

      直到nums1和nums2其中一个数组遍历完了,此时另一个未遍历完的数组中剩余的数都大于result中的元素,将这些数依次加到result后面。

      到现在,我们得到了一个已经包含nums1和nums2中所有元素的排好序的数组result,但是还没有结束,因为我们所要做的是合并两个数组,也就是将nums2合并到nums1中,最后nums1是一个合并好的、排好序的数组,我们当前的nums1还不是。所以,我们还要更新一下nums1,将result中的元素拷贝到nums1中,至此nums1才是题目要求的样子。


    解法二:

    class Solution {
        public void merge(int[] nums1, int m, int[] nums2, int n) {
            int len1 = m - 1;
            int len2 = n - 1;
            int len = m + n - 1;
            while(len1 >= 0 && len2 >= 0) {
                nums1[len--] = nums1[len1] > nums2[len2] ? nums1[len1--] : nums2[len2--];
            }
            // 将nums2数组从下标0位置开始,拷贝到nums1数组中,从下标0位置开始,长度为len2+1
            System.arraycopy(nums2, 0, nums1, 0, len2 + 1);
    
        }
    }

      这种方法相对巧妙一点,没有额外的创建数组,减少了算法的空间复杂度。让我们来看一看这种解法的思路是什么吧。

      解法一的思路是从小到大填数,以此相反,这种解法是从大到小填数据,是在数组nums1上从后往前填数,选择大的填。

      while循环中,当数组nums2中的元素都被填完后,nums1就排好序了;当nums1中的元素被填完,而nums2中的元素还有一些时,语句 System.arraycopy(nums2, 0, nums1, 0, len2 + 1); 就发挥作用了,会将nums2中剩余的元素加到nums1中,使得nums1合并排序完成。

  • 相关阅读:
    Fast RCNN 训练自己数据集 (2修改数据读取接口)
    Caffe Python MemoryDataLayer Segmentation Fault
    Caffe 单独测试添加的layer
    Caffe源码解析7:Pooling_Layer
    Caffe源码解析6:Neuron_Layer
    Caffe源码解析5:Conv_Layer
    Caffe源码解析4: Data_layer
    Caffe源码解析3:Layer
    Caffe源码解析2:SycedMem
    Raft论文学习笔记
  • 原文地址:https://www.cnblogs.com/ruoli-0/p/13697737.html
Copyright © 2011-2022 走看看