首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >O符号和合并两个已经排序的数组

O符号和合并两个已经排序的数组
EN

Stack Overflow用户
提问于 2021-05-23 09:11:32
回答 2查看 391关注 0票数 1

我被告知将两个已经排序的数组,大小不同的A和B合并成一个数组,C在线性时间内。

通过线性时间,我知道这个算法的时间复杂度必须是O(n)。后来,我还被告知在合并数组时执行排序。

我的一个想法是创建一个算法,在两个数组中都有两个指针,指向最小的元素。指向的最小元素将进入新的数组。当一个数组耗尽时,另一个数组的其余元素将复制到新数组中。

由于我几个月前刚开始编程,我发现这很难实现,因此我决定执行合并排序(MS),因为它最类似于上面提到的算法。然而,我关心的是MS本身的时间复杂性- O(nlogn)

然而,考虑到这两个数组已经被排序,MS的时间复杂度会降低还是保持不变?

提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-05-23 09:48:58

您的任务是实现合并算法的合并阶段。mergesort具有O(N.log(N))对数据集排序的复杂性,但每个合并阶段的线性时间与合并集的长度成正比。

以下是这方面的伪代码:

代码语言:javascript
运行
AI代码解释
复制
merge(array a, array b into array c)
    int i = 0, j = 0, k = 0;
    while (i < len(a) and j < len(b)) {
        if (a[i] <= b[j]) {
            c[k++] = a[i++];
        } else {
            c[k++] = b[j++];
        }
    }
    while (i < len(a)) {
        c[k++] = a[i++];
    }
    while (j < len(b)) {
        c[k++] = b[j++];
    }
}

复杂度是线性的,因为每个循环中的每个步骤都将一个元素复制到c数组中,总共需要len(a) + len(b)步骤。

票数 4
EN

Stack Overflow用户

发布于 2021-05-23 09:56:01

将两个大小不同的数组合并成一个数组,C为线性时间。

代码语言:javascript
运行
AI代码解释
复制
int *mergeArrays(const int *array1, const int *array2, size_t size1, size_t size2, int asc)
{
    int *result = malloc((size1 + size2) * sizeof(*array1));
    size_t index1 = 0, index2 = 0;
    size_t i;


    for(i = 0; i < size1 + size2 && index1 < size1 && index2 < size2; i++)
    {   
        if(asc)
        {
            if(array1[index1] > array2[index2]) result[i] = array2[index2++];
            else result[i] = array1[index1++];
        }
        else
        {
            if(array1[index1] > array2[index2]) result[i] = array2[index2++];
            else result[i] = array1[index1++];
        }
    }
    if(index1 == size1) memcpy(result + i, array2 + index2, sizeof(result) * (size2 - index2));
    if(index2 == size2) memcpy(result + i, array1 + index1, sizeof(result) * (size1 - index1));
    return result;
}

https://godbolt.org/z/PY8Ysv319

代码语言:javascript
运行
AI代码解释
复制
int cmpfunc (const void * a, const void * b) {
   return ( *(int*)a - *(int*)b );
}

void sort(int *array, size_t size)
{
    qsort(array, size, sizeof(array[1]), cmpfunc);
}

int *mergeArrays(const int *array1, const int *array2, size_t size1, size_t size2, int asc)
{
    int *result = malloc((size1 + size2) * sizeof(*array1));
    size_t index1 = 0, index2 = 0;
    size_t i;


    for(i = 0; i < size1 + size2 && index1 < size1 && index2 < size2; i++)
    {   
        if(asc)
        {
            if(array1[index1] > array2[index2]) result[i] = array2[index2++];
            else result[i] = array1[index1++];
        }
        else
        {
            if(array1[index1] > array2[index2]) result[i] = array2[index2++];
            else result[i] = array1[index1++];
        }
    }
    if(index1 == size1) memcpy(result + i, array2 + index2, sizeof(result) * (size2 - index2));
    if(index2 == size2) memcpy(result + i, array1 + index1, sizeof(result) * (size1 - index1));
    return result;
}

int main(void)
{
    srand(time(NULL));
    size_t size1 = rand() % 20, size2 = rand() % 20;
    int *mergedArray;

    if(size1 < 5) size1 += 5;
    if(size2 < 5) size2 += 5;

    int array1[size1], array2[size2];

    for(size_t i = 0; i < size1; i++)
        array1[i] = rand();
    for(size_t i = 0; i < size2; i++) 
        array2[i] = rand();
    sort(array1, size1);
    sort(array2, size2);

    for(size_t i = 0; i < size1; i++)
        printf("array1[%2zu] = %d\n", i, array1[i]);
    for(size_t i = 0; i < size2; i++)
        printf("array2[%2zu] = %d\n", i, array2[i]);

    mergedArray = mergeArrays(array1, array2, size1, size2, 1);
    for(size_t i = 0; i < size2 + size1; i++)
        printf("result[%2zu] = %d\n", i, mergedArray[i]);
}

您需要添加内存分配检查、空指针检查等。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67662434

复制
相关文章
双指针--合并两个排序数组
a1=[1,3,4,8,12] a2=[2,5,7,10,12,14] import copy ans=copy.copy(a1) p=0 q=0 while p<len(a1) and q<(len(a2)): if a2[q]>a1[p]: p+=1 else: ans.insert(p+q,a2[q]) q+=1 print(ans+a2[q:])
西西嘛呦
2020/08/26
3570
两个数组合并成一个数组 请把两个数组 ['A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'D1', 'D2'] 和 ['A', 'B', 'C', 'D'],合并为 ['...
方案1 let arr1 = ['A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'D1', 'D2'] let arr2 = ['A', 'B', 'C', 'D'] arr2 = arr2.map(v => `${v}3`); let arr3=[...arr1, ...arr2].sort().map(v => v.replace('3', '')) console.log(arr3) 方案2 let arr1 = ['A1', 'A2', 'B1', 'B
刘嘿哈
2022/10/25
2.1K0
合并两个排序的链表
题目 :输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
名字是乱打的
2022/05/13
8030
[剑指offer] 合并两个排序的链表
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
尾尾部落
2018/09/04
8720
合并两个排序的链表
给定两个递增排序的链表,如何将这两个链表合并?合并后的链表依然按照递增排序。本文就跟大家分享一种解决方案,欢迎各位感兴趣的开发者阅读本文。
神奇的程序员
2022/10/30
8700
合并两个排序的链表
合并两个排序的链表
题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。例如下图中的链表1和链表2,则合并之后的升序链表如链表3所示。 链表结点定义如下: struct ListNode
猿人谷
2018/01/17
1.1K0
合并两个排序的链表
合并两个排序链表
题意 将两个排序链表合并为一个新的排序链表 样例 给出 1->3->8->11->15->null,2->null, 返回 1->2->3->8->11->15->null。 思路 这道题很简单,属于链表的基本操作。 只需要创建一个新的链表与一个指向新链表最后一个节点的指针即可。 当 l1 与 l2 均不为空的情况下,判断 l1 和 l2的大小,把较小值放进新链表的最后一个节点,然后将较小值所处的链表向后移一位,以判断下一个数。 依次循环,直到 l1 或 l2 中有一方为空时,将为空的一方,直接加到新链表后
一份执着✘
2018/06/04
1.6K0
两个排序链表合并
LeetCode 21. Merge Two Sorted Lists 已知两个已排序链表头节点指针L1,L2,将这两个链表合并,合并后仍为有序的,返回合并后的头节点。
小飞侠xp
2018/08/29
1.4K0
[随缘一题]合并两个排序链表
那么其实可以比较两个链表当前节点的值,哪个值小,就把它连接在新链表的后面,并将这个链表的当前指针后移一位.知道某一个链表为空,将另一个链表的所有值链接在后面即可.
呼延十
2019/07/01
1.6K0
算法-合并两个排序的链表
chaibubble
2018/01/02
8960
算法-合并两个排序的链表
合并排序数组 Ⅱ
题意 合并两个排序的整数数组 A 和 B 变成一个新的数组。 注意事项:你可以假设A具有足够的空间(A数组的大小大于或等于 m + n)去添加B中的元素。 ps:m 表示 A 数组的有效元素个数,n 代表 B 数组的有效元素个数。 样例 给出 A = [1, 2, 3, empty, empty], B = [4, 5] 合并之后 A 将变成 [1,2,3,4,5] 思路 可以正序比较 A 数组与 B 数组的每一位,小的放前,其他的元素依次向后移动,但是依次向后移动这个成本太高了。 所以可以考虑倒序
一份执着✘
2018/06/04
9180
合并排序数组
题意 合并两个排序的整数数组A和B变成一个新的数组。 样例 给出A = [1,2,3,4],B = [2,4,5,6],返回 [1,2,2,3,4,4,5,6] 思路 创建一个新的数组,长度是 A 和 B 长度之合,再设三个指针,分别指向 A,B 和新数组的第一个元素,然后遍历两个数组,依次比较每一个元素,较小的数存入新数组中,并将较小值的指针与新数组的指针向后移动一位。最后当遍历完 A 或 B 以后,就将剩余数组的数据依次添加到新数组。 代码实现 class Solution { /**
一份执着✘
2018/06/04
1.1K0
合并两个排序的链表_16
这是第一版本的;思路,如果遍历过程中有一个集合为空了,那么就把另外一个链表里的结点都添加到新链表里,实际上我们这个时候可以直接把另外一个不为空的链表直接加在我们新链表后面了
名字是乱打的
2021/12/23
5110
合并两个排序的链表_16
合并两个排序的单链表
合并单链表,须要找到头结点,对照两个链表头结点后,确定头结点,再确定头结点下一个结点,循环递归的如前面一样操作确定每一个结点位置,同一时候考虑边界条件,假设两个链表为空。则肯定无需合并了,就是空链表,假设一个链表为空,还有一个不为空,则返回不为空的链表。详细分析流程能够看以下的样例:
全栈程序员站长
2022/07/08
4550
合并两个排序的单链表
合并两个有序数组
1,顺序排序,需要额外创建一个数组大小为m+n,然后比较A与B,遍历填充进新数组。然后把数组再次填充回A里面,所以次数为2*(m+n),当m+n趋于无穷大时,2就被忽略了,时间复杂度为O(m+n),空间复杂度为O(m+n)
忧愁的chafry
2022/10/30
1.6K0
合并两个有序数组
合并两个有序数组
自己的写法:对较长的nums1数组使用了双指针法,qp一个在前一个在后,初始时分别指向nums1的第一个元素和第二个元素,分情况讨论有三种,如下代码所示:
大忽悠爱学习
2022/05/05
1.1K0
合并两个有序数组
合并两个有序数组
有两个排序的整数数组,分别是数组1和数组2,将数组2合并到数组1中,合并以后的数组1,仍是有序数组。 提示:
一觉睡到小时候
2019/07/03
1.2K0
合并两个有序数组
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
狼啸风云
2023/10/07
2090
[随缘一题]合并排序数组ii
来源 lintcode-6.合并排序数组 II 描述 合并两个排序的整数数组A和B变成一个新的数组。 样例 给出A=[1,2,3,4],B=[2,4,5,6],返回 [1,2,2,3,4,4,5,6] 解题思路 用两个指针指向两个数组,每次取较小的放入结果数组. 在某个数组全部加入结果后,将另一个数组的值全部加入结果数组. 实现代码 public int[] mergeSortedArray(int[] A, int[] B) { //定义新数组,长度等于两个数组织和 int[] result =
呼延十
2019/07/01
6150
合并两个有序数组
给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。
_kyle
2020/11/13
9000

相似问题

如何利用O(n)时间和O(1)空间代价合并两个排序整数数组

67

在O(logN)中找到两个排序数组的合并数组的中值?

35

如何在O(n)时间和O(1)空间合并同一数组的两个排序部分

21

将两个排序数组合并为O(1)额外空间

14

将两个排序数组合并到O(1)空间中

26
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档