问题
两个整数数组 nums1 和 nums2 按非递减顺序排序,并 提供 两个整数 m 和 n,分别 代表在 nums1 和 nums2 中的整数数量。
在一个单一的过程中,合并 nums1 和 nums2 合并成一个单一的数组。
最后的分类数组应该保存在数组内 nums1 而不是由函数返回。要做到这一点。 nums1 的长度为 m + n 其中第一个元素 m 的项目表示 nums1.的长度为 nums2 的长度是 n.
蛮力方法
我们可以将所有的元素 nums2的所有元素复制到 nums1 然后对整个数组进行排序。这是一个简单但低效的解决方案,因为这不是就地取材,需要O((m+n)log(m+n))时间。
高效方法
我们可以采用3个指针的方法。我们把一个指针放在第一个数组的结束元素处,第二个指针放在第二个数组的结束元素处。假设指针是 one 和 two 分别。第三个指针告诉下一个可用的索引来放置该元素。这被初始化为(size of nums1-1).* 让我们把这个变量称为 finish。
然后我们比较这两个元素。如果 nums1[one] >=nums2[two], 我们 将这个元素放在 nums1 而减少 finish 而反之亦然。
我们这样做,直到所有的指针都大于或等于0。
这是一个就地解决的方法,需要O(m+n)时间。
C++
#include <iostream>
#include <algorithm>
using namespace std;
void solve(int a[], int b[], int m, int n)
{
for (int i = 0; i < m; i++)
{
if (a[i] > b[0])
{
swap(a[i], b[0]);
int first = b[0];
int k;
for (k = 1; k < n && b[k] < first; k++) {
b[k - 1] = b[k];
}
b[k - 1] = first;
}
}
}
int main()
{
int a[] = { 1, 3, 4, 5 };
int b[] = { 2, 3, 10 };
int m = sizeof(a) / sizeof(a[0]);
int n = sizeof(b) / sizeof(b[0]);
solve(a, b, m, n);
for(int i=0;i<m;i++) cout<<a[i]<<" ";
cout<<"\n";
for(int i=0;i<n;i++) cout<<b[i]<<" ";
return 0;
}
Python
def solve(a, b):
m = len(a)
n = len(b)
for i in range(m):
if a[i] > b[0]:
temp = a[i]
a[i] = b[0]
b[0] = temp
first = b[0]
k = 1
while k < n and b[k] < first:
b[k - 1] = b[k]
k = k + 1
b[k - 1] = first
a = [1, 4, 7, 8, 10]
b = [2, 3, 9]
solve(a, b)
print(a)
print(b)
C
void solve(int a[], int b[], int m, int n)
{
for (int i = 0; i < m; i++)
{
if (a[i] > b[0])
{
int temp = a[i];
a[i]=b[0];
b[0]=temp;
int first = b[0];
int k;
for (k = 1; k < n && b[k] < first; k++) {
b[k - 1] = b[k];
}
b[k - 1] = first;
}
}
}
int main()
{
int a[] = { 1, 3, 4, 5 };
int b[] = { 2, 3, 10 };
int m = sizeof(a)/sizeof(a[0]);
int n = sizeof(b)/sizeof(b[0]);
solve(a, b, m, n);
for(int i=0;i<m;i++) printf("%d ",a[i]);
printf("\n");
for(int i=0;i<n;i++) printf("%d ",b[i]);
return 0;
}
输出
[1, 2, 3, 4, 7]
[8, 9, 10]