将两个排好序的序列合并成一个(指针和数组分别实现)

Posted 时间的女儿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将两个排好序的序列合并成一个(指针和数组分别实现)相关的知识,希望对你有一定的参考价值。

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
12         ListNode cur(0);
13         ListNode* temp = &cur;
14         while(l1&&l2){
15             if((l1->val)<=(l2->val)){
16                 temp->next = l1;
17                 l1 = l1->next;
18                 temp = temp->next;
19             }else if((l1->val)>(l2->val)){
20                 temp->next = l2;
21                 l2 = l2->next;
22                 temp = temp->next;
23             }
24         }
25         if(l1){
26             temp->next = l1;
27         }else{
28             temp->next = l2;
29         }
30         return cur.next;
31     }
32 };

2、数组实现,可以和指针采用类似的方法。要申请一个中间数组。若题目要求将合并的数组保存到num1中,我们可以最后将中间数组的值拷贝到num1中。

 1 class Solution {
 2 public:
 3     void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
 4         if(!nums2.size()){
 5             return;
 6         }
 7         vector<int> temp(m+n,0);
 8         int i = 0,j = 0;
 9         int k = 0;
10         while(i<m&&j<n){
11             if(nums1[i]<=nums2[j]){
12                 temp[k] = nums1[i];
13                 i++;
14                 k++;
15             }else if(nums1[i]>nums2[j]){
16                 temp[k] = nums2[j];
17                 j++;
18                 k++;
19             }
20         }
21         if(i<m){
22             while(i<m){
23                 temp[k] = nums1[i];
24                 k++;
25                 i++;
26             }
27         }else{
28             while(j<n){
29                 temp[k] = nums2[j];
30                 k++;
31                 j++;
32             }
33         }
34         nums1.assign(temp.begin(),temp.begin()+m+n);
35    
36     }
37 };

若要求不让使用中间变量,可以使用以下算法

 1 void merge(vector<int>& nums1, int m, vector<int>& nums2, int n)
 2 {
 3     // num1r, num2r read iterators on nums1 and num2r, wi - write iterator
 4     for (int num1r = m - 1, num2r = n - 1, wi = m + n - 1;
 5         num2r >= 0; --wi)
 6     {
 7         if (num1r >= 0 && nums1[num1r] > nums2[num2r])
 8         {
 9             nums1[wi] = nums1[num1r--];
10         }
11         else
12         {
13             nums1[wi] = nums2[num2r--];
14         }
15     }
16 }

两种方法时间复杂度为均为O(n)

以上是关于将两个排好序的序列合并成一个(指针和数组分别实现)的主要内容,如果未能解决你的问题,请参考以下文章

归并排序

递归与分治-合并排序快速排序以及循环赛问题

归并排序的细节讲解与复杂度分析

合并排序

将两个排好序的链表结合成一个有序的链表-附C语言代码

实现2个排好序的子序列合并