问题:
问题一,需要重新排列数组,使得数组的奇数在前面,偶数在后面;
问题二,使得“奇偶奇偶”相间,时间复杂度为O(n)。空间复杂度是O(1)。
分析:
第一个问题,马上想到的就是用两个指针的方法,一个放在头,一个放在尾,同时往中间走,不符合条件,再交换头和尾。
第二个问题,没有什么好的思路,看到网友的思路,还比较认同的,但是时间复杂度有待商榷。
代码如下:
#include<iostream>
using namespace std;
bool isEven(int number)
{
return number & 0x01 == 0x01 ? false : true;
}
/*
* 实现奇数和偶数分开,奇数在前,偶数在后
*/
int ajust(int a[], int len)
{
if (a == NULL || len <= 0)
return -1;
int start = 0;
int end = len - 1;
while (start <= end)
{
while (start <= end && isEven(a[end]))
end--;
while (start <= end && !isEven(a[start]))
start++;
if (start <= end)
{
int temp = a[end];
a[end] = a[start];
a[start] = temp;
start++;
end--;
}
}
return 0;
}
/*
* 实现奇数和偶数相间
*/
int odd_even(int a[], int len)
{
int i = -1;
int j = 0;
bool changed = true; //这个标志位非常重要,可以理解为,i和j之间相差不能超过1
while (j < len)
{
if (isEven(j) == !isEven(a[j])) //如果所在位置正确,不进行交换,直接判断i是否自增
{
if(changed)
i++;
}
else
{
changed = false;
if (!isEven(i + 1) == isEven(a[j]))
{
i++;
int temp = a[i];
a[i] = a[j];
a[j] = temp;
j = i; //将j重新赋值,但是这会导致时间复杂度超过O(n)
changed = true;
}
}
j++;
}
return 0;
}
int main()
{
int a[] =
{ 6, 8, 10, 1, 3, 5 };
ajust(a, sizeof(a) / sizeof(a[0]));
for (int i = 0; i < (int) (sizeof(a) / sizeof(a[0])); i++)
cout << a[i] << " ";
cout << endl;
odd_even(a, sizeof(a) / sizeof(a[0]));
for (int i = 0; i < (int) (sizeof(a) / sizeof(a[0])); i++)
cout << a[i] << " ";
return 0;
}
总结:
如果修改问题,改成奇数和偶数的相对顺序不变,又该如何做呢?