力扣面试题10.01:利用双指针法原地合并有序数组

贾蔷
• 阅读 2

力扣面试题10.01:利用双指针法原地合并有序数组

一、题目解读

力扣面试题10.01要求将两个有序数组A和B合并成一个有序数组,且合并结果需存储在数组A中(原地修改)。需确保合并后的A元素按升序排列,同时考虑A末尾可能存在无效元素(填充0)。核心挑战在于如何在O(m+n)时间复杂度内完成合并,避免使用额外空间。

二、解题思路

采用“双指针从后向前合并”策略:

  1. 初始化三个指针:i指向A的有效末尾,m-1;j指向B末尾n-1;k指向A总末尾m+n-1。

  2. 从后向前比较A[i]与B[j],将较大元素放入A[k],同时移动对应指针。

  3. 若B剩余元素未处理完,直接复制到A头部。

此思路利用A的额外空间(原无效部分)存放合并结果,避免新数组创建。

三、解题步骤

  1. 初始化指针:i=m-1,j=n-1,k=m+n-1,确保遍历从末尾开始。

  2. 双指针比较合并:

● 若A[i]>B[j],将A[i]放入A[k],i、k左移;

● 否则(含A[i]≤B[j]),将B[j]放入A[k],j、k左移。

● 循环直至A或B遍历完毕。

  1. 处理剩余元素:若B有剩余(j≥0),直接将B[j]填入A[k],直至B为空。

  2. 结果验证:此时A已有序,无需额外排序

四、代码与注释

class Solution {  
public:  
    void merge(vector<int>& A, int m, vector<int>& B, int n) {  
        // 初始化指针:i指向A末尾,m-1;j指向B末尾n-1;k指向A总末尾m+n-1  
        int i = m - 1, j = n - 1, k = m + n - 1;  

        // 从后向前遍历,比较并合并  
        while (i >= 0 && j >= 0) {  
            if (A[i] > B[j]) {  
                A[k--] = A[i--];  // A的元素较大,放入末尾  
            } else {  
                A[k--] = B[j--];  // B的元素较大或相等,放入末尾  
            }  
        }  

        // 若B中还有剩余元素,全部复制到A中  
        while (j >= 0) {  
            A[k--] = B[j--];  
        }  

        // A中剩余元素已在正确位置,无需处理  
    }  
};

五、总结

双指针法巧妙利用原数组空间,实现原地合并,时间复杂度O(m+n),空间复杂度O(1)。该解法核心在于从后向前操作,避免元素覆盖问题,适用于需高效处理的面试场景。掌握此类技巧,可显著提升算法设计与优化能力。

来源:力扣面试题10.01:利用双指针法原地合并有序数组

点赞
收藏
评论区
推荐文章
先知 先知
4年前
C 语言代码大全
1两个数组的合并题目描述已知数组a中有m个按升序排列的元素,数组b中有n个按降序排列的元素,编程将a与b中的所有元素按降序存入数组c中。输入输入有两行,第一行首先是一个正整数m,然后是m个整数;第二行首先是一个正整数n,然后是n个整数,m,n均小于等于1000000。输出输出合并后的mn个整数,数据之间用空格隔开。输出占一行。样例输入4
九路 九路
4年前
二分查找法的递归和非递归的实现
//二分查找法非递归实现,在一个有序的数组中查找e元素的位置,找不到返回1publicstaticintbinarySearch(intdata,inte){intl0;intrdata.length1;while(l<r){
腾讯T2亲自讲解!Android-App的设计架构经验谈
正文我们今天将说明以下14种模式:1.滑动窗口2.二指针或迭代器3.快速和慢速指针或迭代器4.合并区间5.循环排序6.原地反转链表7.树的宽度优先搜索(TreeBFS)8.树的深度优先搜索(TreeDFS)9.TwoHeaps10.子集11.经过修改的二叉搜索12.前K个元素13.K路合并14.拓扑排序我们开始吧!1.滑动窗口滑动窗口模式
Wesley13 Wesley13
3年前
PHP二维数据排序,二维数据模糊查询
一、因为项目中的一个报表需要合并三个表的数据,所以分表查询再合并数据,利用PHP数组函数进行排序,搜索。三表合并后的数组结构如下:Array(0Array(history_id12sla_group_
Wesley13 Wesley13
3年前
Union Find
并查集是在各个不相交集合中查找某元素存在否,可以接近常数级查找例如,图的连通性,最近公共祖先等问题。一般用森林数组实现。一般有2个操作,查找(find)和合并(union)查找:从集合中查找元素x是否存在。合并:如果2个集合不想交则可以合并操作,一般方法是高度低的合并到高度高的。初始化每个元素都可以是一个单独的集合,然后不断引入关系来合并他
Stella981 Stella981
3年前
LeetCode:283.移动零——简单
题目:283.移动零:给定一个数组nums,编写一个函数将所有0移动到数组的末尾,同时保持非零元素的相对顺序。示例:输入:0,1,0,3,12输出:1,3,12,0,0说明:1.必须在原数组上操作,不能拷贝额外的数组。2.尽量减少操作
菜园前端 菜园前端
2年前
什么是归并排序?
原文链接:什么是归并排序(mergeSort)?主要分成两部分实现,分、合操作:分:把数组分成两半,在递归地对子数组进行"分"操作,直到分成一个个单独的数合:把两个数组合并为有序数组,再对有序数组进行合并,直到全部子数组合并为一个完整数组归并排序就是采用了
贾蔷 贾蔷
1个月前
洛谷P1102题解:利用哈希表优化的数对统计 C++代码解析
一、题目解读P1102题要求处理一组整数与常数C,统计数组中是否存在元素A与B满足ABC。用户需输出满足条件的数对数量。题目关键在于快速判断是否存在互补元素,时间复杂度需优化以避免暴力遍历。二、解题思路采用(unorderedmap)实现高效统计。首先遍
深度学习 深度学习
1个月前
LeetCode 2576题解:双指针法求解最多标记下标(排序+贪心策略)
一、题目解读2576题要求在一个整数中寻找最多可标记的下标对:若nums法”的组合思路:1.排序预处理:对原数组nums进行升序排序,确保相同元素聚集,便于后续配对。2.双划分:将排序后的数组分为左右两半(左指针left0,右指针rightn/2),从
贾蔷 贾蔷
2星期前
力扣15题三数之和解法(C++双指针算法详解)
一、题目解读15题()要求在一个包含n个整数的中,找出所有三个数之和为0的组合,且每个组合的元素不能重复。题目考察数组遍历、与技巧的结合,是经典的多问题,对时间复杂度优化有较高要求。二、解题思路采用“双指针”策略:首先对原数组排序,然后固定第一个数,通过左