在编程中,常常会遇到一些简单的数组操作问题,其中之一就是如何将数组中的奇数和偶数分离,奇数排在前面,偶数排在后面。这个问题虽然看起来简单,但如何高效地实现是我们需要思考的问题。
本文将通过C语言来实现这一功能,并且使用双指针法(Two-pointer approach)来优化解决方案。通过这种方法,我们可以在O(n)的时间复杂度内完成数组奇偶分离,而且空间复杂度为O(1),即只需要常数空间。
给定一个整数数组,我们需要将其中的所有奇数移动到数组的前面,所有偶数移动到数组的后面。要求:
为了实现上述功能,我们可以采用双指针法。基本思路是通过两个指针,一个从数组的左端开始,另一个从右端开始,进行交换操作。具体步骤如下:
通过这种方法,我们可以在一次遍历中完成奇偶分离的任务,时间复杂度为O(n),而空间复杂度仅为O(1),因为我们只用了常数的额外空间。
下面是基于双指针法实现的C语言代码:
#include
void adjustArray(int arr[], int sz) {
int left = 0; // 左指针,从数组的头部开始
int right = sz - 1; // 右指针,从数组的尾部开始
while (left < right) {
// 找到左指针指向的是偶数
while (left < right && arr[left] % 2 != 0) {
left++; // 向右移动左指针
}
// 找到右指针指向的是奇数
while (left < right && arr[right] % 2 == 0) {
right--; // 向左移动右指针
}
// 当左指针指向偶数,右指针指向奇数时,交换它们
if (left < right) {
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
}
}
int main() {
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int sz = sizeof(arr) / sizeof(arr[0]);
// 调整数组中的奇偶顺序
adjustArray(arr, sz);
// 输出调整后的数组
printf("调整后的数组:");
for (int i = 0; i < sz; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
left
和 right
,分别指向数组的开始和末尾。假设我们有一个包含奇数和偶数的数组:
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
经过上述算法处理后,数组中的奇数和偶数将被分开,输出可能是:
调整后的数组:1 9 3 5 7 6 4 8 2 10
这里,奇数部分 [1, 9, 3, 5, 7]
被移到了数组的前面,偶数部分 [6, 4, 8, 2, 10]
被移到了后面。
这种方法非常高效,尤其适用于需要在空间有限的情况下处理大数组的场景。
通过双指针法,我们可以在O(n)的时间复杂度内完成数组的奇偶分离,并且空间复杂度为O(1),这使得算法非常高效,适用于大规模数据处理。双指针法是一种常用的技巧,在许多数组和链表的操作中都能派上用场。如果你还不熟悉双指针法,建议深入理解并多加练习。