合并两个有序数组(双指针解题)

1.题目:牛客网 NC22 (合并两个有序的数组)

描述
给出一个整数数组A和有序的整数数组B,请将数组B合并到数组A中,变成一个有序的升序数组
注意:
1.可以假设A数组有足够的空间存放B数组的元素,A和B中初始的元素数目分别为m和n,A的数组空间大小为m+n
2.不要返回合并的数组,返回是空的,将数组B的数据合并到A里面就好了
3.数组A在[0,m-1]的范围也是有序的

例1:
A: [4,5,6,0,0,0],m=3
B: [1,2,3],n=3
合并过后A为:
A: [1,2,3,4,5,6]

2.解题思路(一般解法)

把B数组合并到A数组后,形成新的大小为为m+n的A数组,对新的A数组排序。
此揭发缺点:没有用到A和B皆是升序这个特点。后面排序浪费了时间。

class Solution {
    
    
public:

    void merge(int A[], int m, int B[], int n) {
    
    
        for(int i=0;i<n;i++)
            A[m+i]=B[i];
        //对A进行排序,冒泡排序;也可直接使用sort对A进行排序
        int len=m+n;
        for(int i=0;i<len-1;i++)
            for(int j=0;j<len-1-i;j++)
            {
    
    
                if(A[j]>A[j+1])
                {
    
    
                    int temp=A[j];
                    A[j]=A[j+1];
                    A[j+1]=temp;
                }
            }        
    }
};

3.解题思路(双指针尾插法)
在这里插入图片描述
如图所示,采用3个指针,p1指向A的尾端,即m-1处,p2指向B的尾端,即n-1处。再用一个指针p指向扩容后数组A的m+n-1处。
往左边走,是p1和p2的移动方向。
每次,比较p1和p2所指向的值,大的那一个值,放入p所指向的位置。
需要注意边界条件,比如当A指针的p1走到最边,B指针p2还没走完时,把B剩下的内容按对应位置放入A即可。

代码如下:

class Solution {
    
    
public:

    void merge(int A[], int m, int B[], int n) {
    
    
        int p1=m-1,p2=n-1;
        for(int p=m+n-1;p1>=0&&p2>=0;p--)
        {
    
    
            if(A[p1]>B[p2])
                A[p]=A[p1--];
            else
                A[p]=B[p2--];
        }
        //A指针先走完的情况,B中剩余元素直接copy至A对应位置即可;
        while(p2>=0)
        {
    
    
            A[p2]=B[p2];
            p2--;
        }
    }
};

思考留个简单小问题,以测试你是否理解了 ):

如代码中,为什么只考虑了A指针先走完的情况,没有考虑B指针先走完的情况?

おすすめ

転載: blog.csdn.net/t18438605018/article/details/119844740