力扣题目地址: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中就行了,排序算法有很多,我使用的是简单的冒泡排序。
开始我们的解题之旅:
- 合并数组。
- 冒泡排序。
代码实现如下:
/**
* 合并排序数组
* @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数组中。
- 设置两个指针。
- 创建一个新链表存放值,并设置该链表的指针。
- 遍历两个有序链表,对比每次的头结点,小的放入新链表中,并将该链表指针后移一位。循环直至完成遍历。
- 将新的有序链表复制到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,到这里就大功告成了,这里就不写测试数据了,跟上面的一模一样,换个方法名就行了。
不忘初心,砥砺前行。