将两个排好序的序列合并成一个(指针和数组分别实现)
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)