LeetCode-数据结构-合并排序的数组

力扣题目地址:https://leetcode-cn.com/problems/sorted-merge-lcci/

首先看题目
给定两个排序后的数组 A 和 B,其中 A 的末端有足够的缓冲空间容纳 B。 编写一个方法,将 B 合并入 A 并排序。

初始化 A 和 B 的元素数量分别为 m 和 n。

示例

输入:
A = [1,2,3,0,0,0], m = 3
B = [2,5,6],       n = 3

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

解决思路
首先明白我们要干啥,合并排序两个数组。第一时间想到的方法就是先合并数组,然后进行排序。合并很简单,循环把B添加到A中就行了,排序算法有很多,我使用的是简单的冒泡排序。

开始我们的解题之旅:

  1. 合并数组。
  2. 冒泡排序。

代码实现如下:

	/**
     * 合并排序数组
     * @param A
     * @param m
     * @param B
     * @param n
     * @author GeYuxuan 2020-03-03 22:05:47
     * @return void
     */
    public void merge(int[] A, int m, int[] B, int n) {
        //先将元素全部放入A中,然后排序
        for(int i = 0; i < n; i++) {
            A[i+m] = B[i];
        }
        //冒泡排序算法
        for(int i = 0; i < m + n; i++) {
            for(int j = 0; j < m + n - 1 - i; j++) {
                if(A[j+1] < A[j]){
                    int temp = A[j];
                    A[j] = A[j+1];
                    A[j+1] = temp;
                }
            }
        }
    }

然后我们测试一下:

package com.gyx.util;

/**
 * description
 * @author GeYuxuan 2020/02/29 17:35
 */
public class Test {

    public static void main(String[] args) {
        int A[] = {1,2,3,0,0,0};int m=3;
        int B[] = {2,5,6,0,0,0};int n=3;
        Solution solution = new Solution();
        solution.merge(A,m,B,n);
        for(int i = 0; i < m+n; i++) {
            System.out.println(A[i]);
        }
    }
}

打印结果: 1,2,2,3,5,6

ok,这就是最常规的解法了。但是我们注意题目,题目给的是有序数组,我们这中先合并再排序的解法完全没有用到有序数组这个条件,所以我们还可以有更优的算法来解决这个问题。

看完官方题解之后,我自己用java完成了双指针法的实现。

解决思路
我们可以用昨天链表的思路来解决这个问题。我们把两个有序数组当做两个有序链表,所有我们就有pa,pb两个指针。每次取出头结点,把头结点进行对比,将较小的那个一个放入新的链表中,然后把取出值的有序链表的指针后移一位,直到两个有序链表的值都遍历完成。
最后一步就是讲排好序的新链表,复制到A数组中。

  1. 设置两个指针。
  2. 创建一个新链表存放值,并设置该链表的指针。
  3. 遍历两个有序链表,对比每次的头结点,小的放入新链表中,并将该链表指针后移一位。循环直至完成遍历。
  4. 将新的有序链表复制到A中。

代码实现如下:

	/**
     * 合并排序数组  -双指针法
     * @param A
     * @param m
     * @param B
     * @param n
     * @author GeYuxuan 2020-03-03 22:05:47
     * @return void
     */
    public void merge1(int[] A, int m, int[] B, int n) {
    	//1.设置两个指针
        int pa = 0,pb = 0;
        //2.1 创建一个新链表存放值
        int[] result = new int[m+n];
        //2.2 设置新链表的指针
        int cur;
        //3.遍历两个有序链表
        while (pa < m || pb< n){
        	//pa指针到底,pb没有,说明B数组还有值,继续放值,指针后移
            if(pa == m){
                cur = B[pb++];
            }
            //pb指针到底,pa没有,说明A数组还有值,继续放值,指针后移
			else if(pb== n){
                cur = A[pa++];
            }
			//对比每次的头结点,较小值放入新链表中,并将该数组指针后移
			else if(A[pa]<B[pb]){
                cur = A[pa++];
            }else{
                cur = B[pb++];
            }
            //设置新链表指针的值
            result[pa+pb-1] = cur;
        }
        //4.将新的有序链表复制到A中
        for(int i = 0; i < m + n; i++) {
            A[i] = result[i];
        }
    }

ok,到这里就大功告成了,这里就不写测试数据了,跟上面的一模一样,换个方法名就行了。

不忘初心,砥砺前行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值