力扣面试经典150 88. 合并两个有序数组 归并排序的merge函数

题目链接

规定了时间我首先想到的是归并排序,以时间换空间,题目要求时间复杂度O(m+n)

提示:

复制代码
nums1.length == m + n
nums2.length == n
0 <= m, n <= 200
1 <= m + n <= 200
-109 <= nums1[i], nums2[j] <= 109

而且这个题理论上,是合并,所以得把最后合并的结果放到nums1\[\]上

下面是代码

java 复制代码
class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
   vector<int> temp(nums1.begin(),nums1.begin()+m);
   int p=0;
   int p1=0;
   int p2=0;
   while(p1<m&&p2<n){if(temp[p1]<=nums2[p2])
    nums1[p++]=temp[p1++];else
    nums1[p++]=nums2[p2++];
   }

while(p1<m)nums1[p++]=temp[p1++];
while(p2<n)nums1[p++]=nums2[p2++];


    }
};

然后再复习一下归并排序

这么多年了,发现自己学习算法过于死板

其实归并排序是一棵归并排序二叉树。

那么一涉及到树就很容易理解,这里头有递归,所以归并排序是由递归和merge函数组合来实现的,那个大的递归函数就是

java 复制代码
void mergeSort(vector<int>& arr, int l, int r){
if(l>=r) return;
int mid=(l+r)/2;
mergesort(arr,l,mid);
mergesort(arr,mid,r);
merge(arr,l,mid,r);
}

下面是完整的归并排序的代码

java 复制代码
#include <iostream>
#include <vector>
using namespace std;

// 合并两个有序区间 [l, mid] 和 [mid+1, r]
void merge(vector<int>& arr, int l, int mid, int r) {
    vector<int> temp(r - l + 1);
    int i = l;
    int j = mid + 1;
    int k = 0;

    while (i <= mid && j <= r) {
        if (arr[i] <= arr[j]) {
            temp[k++] = arr[i++];
        } else {
            temp[k++] = arr[j++];
        }
    }

    while (i <= mid) temp[k++] = arr[i++];
    while (j <= r) temp[k++] = arr[j++];

    // 复制回原数组
    for (int p = 0; p < temp.size(); ++p) {
        arr[l + p] = temp[p];
    }
}

// 归并排序递归
void mergeSort(vector<int>& arr, int l, int r) {
    if (l >= r) return;
    int mid = (l + r) / 2;
    mergeSort(arr, l, mid);
    mergeSort(arr, mid + 1, r);
    merge(arr, l, mid, r);
}

int main() {
    vector<int> arr = {5, 2, 9, 1, 5, 6, 3, 8};

    cout << "排序前:";
    for (int x : arr) cout << x << " ";
    cout << endl;

    mergeSort(arr, 0, arr.size() - 1);

    cout << "排序后:";
    for (int x : arr) cout << x << " ";
    cout << endl;

    return 0;
}

直接从后面替换插入的方法

java 复制代码
class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
  int i=nums1.size()-1;
  n--;
  m--;
    while(n>=0){
        while(m>=0&&nums1[m]>nums2[n]){
            swap(nums1[i--],nums1[m--]);
        }
        swap(nums1[i--],nums2[n--]);
    }
    }
};
相关推荐
倒头就睡的小比特2 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!2 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
晨米酱2 天前
AGENTS.md:Agent 的上下文策略层
面试·架构·agent
猎头南楼2 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
旖旎夜光2 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark2 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her12 天前
并查集-听课笔记
笔记·算法·并查集
码流子2 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
彧azz2 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
another heaven2 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法