剑指offer-合并两个排序的数组

题目要求

已知两个已经排好序的数组A1,A2,将两个排序的数组合并到一起,并使之合并的数组也是排序的数组。
例如已知两个排序的数组是 {1,2,3,4},{2,4,5,6},那么合并后的排序的数组是{1,2,2,3,4,4,5,6}

思路

1.如果遍历两个数组的话,从前遍历两个数组,判断两个数组中的大小,从而合并成一个大的排好序的数组的话,这种解决方案,会出现多次复制一个数字的情况,更好的额解决方案,是从尾比较A1和A2中的数字,并把较大的数字复制到A1中的位置。

2.解决方案考虑了多种情况:

  • 数据A和数组B为空的情况
  • 数组A中的最大值小于B中的最小值
  • 数组A中的最小值大于B中的最大值
  • 如果以上的情况都未出现,那么如果A.length 的长度不等于 B.length.那么就会出现某一个已经数组(比如时候A)已经比较完了,那么剩下的数组(比如说B),将剩下的数组直接拷贝到目标数组中即可

代码实现

package com.offer.test;

/**  
 * 
 * 样例  1:
	输入: A=[1], B=[1]
	输出:[1,1]
	
	样例解释: 
	返回合并后的数组。

样例 2:
	输入: A=[1,2,3,4], B=[2,4,5,6]
	输出: [1,2,2,3,4,4,5,6]
	
	样例解释: 
	返回合并后的数组。
 * @author zhouwenchen@021.com  
 * @date 2019年6月13日 上午9:44:09 
 */
public class SortArr {
	public static void sortArr(int[] A, int[] B) {
		// 将数组A拷贝到数组C中,数组C的长度是等于A.length+B.length
		int[] C = new int[A.length + B.length];

		// 1.解决问题1.可能某一个数组的最大值小于另个数组的最小值
		int a = A.length - 1;
		int b = B.length - 1;
		/**
		 * 可能某一个数组为空
		 */
		if (A.length == 0) {
			System.arraycopy(B, 0, C, 0, b + 1);
			return;
		}
		if (B.length == 0) {
			System.arraycopy(A, 0, C, 0, a + 1);
			return;
		}
		// A中的最大值小于B中的最小值,直接复制到数组C中
		if (A[a] < B[0]) {
			System.arraycopy(A, 0, C, 0, a + 1);
			System.arraycopy(B, 0, C, a + 1, b + 1);
			return;
		}
		// B中最大值小于A中的最小值,直接复制到数组C中
		if (B[b] < A[0]) {
			System.arraycopy(B, 0, C, 0, b + 1);
			System.arraycopy(A, 0, C, b + 1, a + 1);
			return;
		}
		// 从数组的高位置开始判断
		for (int i = C.length - 1; i >= 0; i--) {
			// A数组已经判断完了,直接将剩下的B数组复制到C中
			if (a < 0) {
				System.arraycopy(B, 0, C, 0, b + 1);
				continue;
			}
			// B数组已经判断完了,直接将剩下的A数组复制到C中
			if (b < 0) {
				System.arraycopy(A, 0, C, 0, a + 1);
				continue;
			}
			if (A[a] >= B[b]) {
				C[i] = A[a];
				a--;
			} else {
				C[i] = B[b];
				b--;
			}
		}
		System.out.println(C.toString());
	}
	
	
	/**
	 * 问题1,可能某一个数组的最大值小于两个数组的最小值。
	 * @param args
	 */
	public static void main(String[] args) {
		// 测试案例1:
//		int[] A = new int[] { 1, 2, 3, 4};
//		int[] B = new int[] { 2, 4, 5, 6 };
		
		// 测试案例2
//		int[] A = new int[] { 1, 2, 3, 4};
//		int[] B = new int[] { 5, 6, 7, 8 };
		
		// 测试案例3
		int[] A = new int[] { };
		int[] B = new int[] { 5, 6, 7, 8 };
		sortArr(A, B);
	}
}

20200518 新增实现方式

/**
	 * 将两个有序的数组添加到更大的数组中,然后直接使用Collections.sort()
	 * @param A
	 * @param B
	 */
	public static void sortArr1(int[] A, int[] B) {
		int[] C = new int[A.length + B.length];
		System.arraycopy(A,0,C,0,A.length);
		System.arraycopy(B,0,C,A.length,B.length);
		Arrays.sort(C);
	}

	/**
	 * 创建一个大数组,从数组末尾开始填充数据,
	 * @param A
	 * @param B
	 */
	public static void sortArr2(int[] A, int[] B) {
		int alen = A.length - 1;
		int blen = B.length - 1;
		int[] C = new int[A.length + B.length];
		int clen = C.length - 1;
		while (alen >= 0 && blen >= 0) {
			if (A[alen] > B[blen]) {
				C[clen--] = A[alen--];
			} else {
				C[clen--] = B[blen--];
			}
		}
		// 判断 A 或者 B已经没有数据了
		if (alen >= 0) {
			System.arraycopy(A, 0, C, 0, alen - blen);
		}
		if (blen >= 0) {
			System.arraycopy(B, 0, C, 0, blen - alen);
		}
		System.out.println(C);
	}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值