题目
给你两个按非递减顺序排列的整数数组nums1 和nums2(都是有序的),另有两个整数m 和n ,分别表示 numsl 和nums2 中的元素数目。请你合井 nums2到nums1 中,使合并后的数組同样按 非递减顺序排列。注意:最終,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m+n,其中前 m个元素表示应合并的元素,后n个元素为 0,应忽略。 nums2 的长度为n。
分析图示
文字解析:
这段代码实现了合并两个有序数组的功能。它使用了三个指针end1、end2和end来分别指向nums1、nums2和合并后的结果数组nums1的末尾。
首先,我们初始化指针end1为nums1的最后一个元素的索引,指针end2为nums2的最后一个元素的索引,指针end为合并后的结果数组nums1的最后一个位置的索引。
然后,我们使用一个循环来比较nums1和nums2中的元素,并将较大的元素放入合并后的结果数组nums1的末尾。每次比较后,我们将相应的指针向前移动一位,并将结果存储在合并后的结果数组的当前位置。直到其中一个数组的元素全部被合并完。
接下来,如果nums2中还有剩余的元素,我们将它们依次放入合并后的结果数组nums1的剩余位置。
最后,合并完成后,nums1中就存储了合并后的有序数组。
在完成这段代码之前,需要注意以下几点:
1. 确保nums1和nums2是按非递减顺序排列的,否则合并后的结果可能不是有序的。
2. 确保nums1的长度足够大,能够容纳合并后的结果。即nums1的长度应为m+n。
3. 在合并过程中,我们是从后往前遍历数组,因此需要确保nums1和nums2中的元素都在有效的索引范围内。
4. 如果nums1和nums2的长度为0,或者其中一个数组的长度为0,那么不需要进行合并操作,直接返回即可。
示例代码
void merge(int* nums1, int m, int* nums2, int n) {
int i = m - 1;
int j = n - 1;
int k = m + n - 1;
while (i >= 0 && j >= 0) {
if (nums1[i] > nums2[j]) {
nums1[k] = nums1[i];
i--;
} else {
nums1[k] = nums2[j];
j--;
}
k--;
}
while (j >= 0) {
nums1[k] = nums2[j];
j--;
k--;
}
}
题外话
strncpy函数
strncpy
函数是C语言中的字符串处理函数,用于将一个字符串的一部分复制到另一个字符串中。它的函数原型如下:char* strncpy(char* destination, const char* source, size_t num);
注意:此函数是运用于字符串数据类型的。
qsort函数和memcpy函数的结合运用
qsort函数
qsort
函数是一个标准库函数,用于对数组进行快速排序。它的函数原型如下:void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
base
:指向要排序的数组的指针。nmemb
:数组中元素的个数。size
:每个元素的大小(以字节为单位)。compar
:比较函数的指针,用于指定元素之间的比较规则。
比较函数compar的原型如下:
int compar(const void *a, const void *b);
比较函数接受两个指向元素的指针,并返回一个整数值,表示两个元素的大小关系。返回值的含义如下:
- 小于0:表示a小于b。
- 等于0:表示a等于b。
- 大于0:表示a大于b。
qsort
函数会根据比较函数的返回值对数组进行排序。排序是原地进行的,即不会创建新的数组,而是直接修改原数组。
使用:
#include <stdio.h>
#include <stdlib.h>
int compare(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
int main() {
int arr[] = {5, 2, 8, 1, 9};
int n = sizeof(arr) / sizeof(arr[0]);
qsort(arr, n, sizeof(int), compare);
printf("Sorted array: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
memcpy函数
memcpy
函数是一个标准库函数,用于在内存之间进行字节级别的拷贝。它的函数原型如下:void *memcpy(void *dest, const void *src, size_t n);
dest
:指向目标内存区域的指针,即拷贝的目的地。src
:指向源内存区域的指针,即拷贝的来源。n
:要拷贝的字节数。
memcpy
函数将源内存区域的内容拷贝到目标内存区域中,拷贝的字节数由参数n
指定。拷贝过程是按字节进行的,不会考虑数据类型。
综合使用
代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void merge(int* nums1, int m, int* nums2, int n) {
// 将nums2拷贝到nums1的后面
memcpy(nums1 + m, nums2, n * sizeof(int));
// 对nums1进行排序
qsort(nums1, m + n, sizeof(int), compare);
}
int compare(const void* a, const void* b) {
return (*(int*)a - *(int*)b);
}
int main() {
int nums1[6] = {1, 2, 3, 0, 0, 0};
int nums2[3] = {2, 5, 6};
int m = 3;
int n = 3;
merge(nums1, m, nums2, n);
printf("Merged array: ");
for (int i = 0; i < m + n; i++) {
printf("%d ", nums1[i]);
}
printf("\n");
return 0;
}
缺点:由于qsort
函数是使用快速排序算法实现的,其平均时间复杂度为O(nlogn),其中n是nums1
数组和nums2
数组的总长度。虽然这个时间复杂度在大多数情况下是可以接受的,但在某些情况下可能会比较耗时。