P15-合并两个有序数组-双指针

//合并两个有序数组
/*
* 两个有序整数数组nums1和nums2,将nums2合并到nums1中,使nums1成为一个有序数组
* 初始化nums1和nums2的元素数量分别为m和n。假设nums1的空间大小等于m+n,这样他就有足够的空间保存来自nums2的元素
* */
public class P15 {

    public static void main(String[] args) {
        int[] nums1 = new int[]{1,3,5,7,9,0,0,0,0};
        int[] nums2 = new int[]{2,4,6,8};
//        System.out.println(Arrays.toString(merge(nums1, 5, nums2, 4)));
//        System.out.println(Arrays.toString(merge2(nums1, 5, nums2, 4)));
        System.out.println(Arrays.toString(merge3(nums1, 5, nums2, 4)));
    }

    public static int[] merge(int[] nums1, int m, int[] nums2, int n){

        //nums2从0位置开始拷贝到nums1的m位置上,拷贝长度为n
        System.arraycopy(nums2, 0, nums1, m, n);

        //时间 O((n+m)log(n+m))
        Arrays.sort(nums1);

        return nums1;
    }

    //双指针
    //空间换时间,搞一个空数组,两个指针分别指向两个数组元素,比较大小,存进新数组中,存了的指针加1
    public static int[] merge2(int[] nums1, int m, int[] nums2, int n){

        //因为题目是要nums1的数组,所有这里先拷贝nums1再把nums1作为存放结果的数组
        int [] nums1_copy = new int[m];
        System.arraycopy(nums1, 0, nums1_copy, 0, m);

        //指向nums1_copy
        int p1 = 0;
        //指向nums2
        int p2 = 0;

        //指向nums1
        int p = 0;

        //其中一个越界就是已经比较完了,把剩余的数据插入到后面就可以了
        while(p1 < m && p2 < n){
            //被选中的才++
            nums1[p++] = nums1_copy[p1] < nums2[p2] ? nums1_copy[p1++] : nums2[p2++];
        }

        //会有某个数组还没拷贝完
        if(p1 < m){
            System.arraycopy(nums1_copy, p1, nums1, p, m+n-p);
        }
        if(p2 < n){
            System.arraycopy(nums2, p2, nums1, p, m+n-p);
        }

        return nums1;
    }

    //上面的方法是需要额外空间的,可以利用nums1的空余空间进行优化
    public static int[] merge3(int[] nums1, int m, int[] nums2, int n){

        //从后往前遍历
        //指向nums1_copy最后一个下标
        int p1 = m-1;
        //指向nums2最后一个下标
        int p2 = n-1;

        //指向nums1的最后一个下标
        int p = m+n-1;

        while(p1 >= 0 && p2 >= 0){
            //被选中的才--
            nums1[p--] = nums1[p1] > nums2[p2] ? nums1[p1--] : nums2[p2--];
        }

        //自己画个图想一想
        System.arraycopy(nums2, 0, nums1, 0, p2+1);

        return nums1;
    }
}

 

posted @ 2022-04-11 11:26  YonchanLew  阅读(33)  评论(0)    收藏  举报