我的思路:(很low)
void odevity_swap(int *arr, int size)
{
if (size < 2)
{
return;
}
int i = 0;
int j = 0;
for(j = 0; j<size-1; j++)
{
for(i = 0; i<size-1; i++)
{
if(0 == arr[i]%2)
{
arr[i] ^= arr[i+1];
arr[i+1] ^= arr[i];
arr[i] ^= arr[i+1];
}
}
}
for(i = 0; i<size; i++)
{
printf("%d\n", arr[i]);
}
}
牛客网解题思路:(很高级)
如果是强解的话,就可以从头扫描这个数组,每碰到一个偶数时,拿出这个数字,并把位于这个数字后面的所有数字都往前挪动一位,这种解法显然是O(n^2)的,不用想都知道,这不可能通过测试的。其实,向数组类的问题,尤其是这种分为两部分的,我们都可以借鉴快排思想。
首先,设置前指针指向第一个数,并且只向后移动;
然后,.设置第二个指针指向最后一个数,并且只向前移动;
最后,在两个指针相遇之前,第一个指针总是位于第二个指针的前面。如果第一个指针指向的数字是偶数,并且第二个指针指向的数字是奇数,我们就交换这两个数字。
卧槽,测试不能通过!!!原来快排是不稳定的,而此题目要求相对位置不变!!!
其实,要想保证原有次序,则只能顺次移动或相邻交换。那么依然设置两个指针:
首先,one从左向右遍历,找到第一个偶数;
然后,two从one+1开始向后找,直到找到第一个奇数;
接着,将[one....two-1]的元素整体后移一位;
最后将找到的奇数放入one位置,然后one++。
void odevity_swap1(int *arr, int size)
{
if (size < 2)
{
return;
}
int one = 0;
int two = 0;
while (one < size)
{
while (one < size && (arr[one] & 0x1) == 1)//查找第一位偶数
{
one++;
}
two = one + 1;
while (two < size && (arr[two] & 0x1) != 1)//查找偶数后的第一位奇数
{
two++;
}
if (two < size) //奇偶互换
{
int temp = arr[two]; //将偶数位后的第一位奇数保存起来
for (int i = two - 1; i >= one; i--) //将[one...two-1]整体向后移动一位
{
arr[i + 1] = arr[i];
}
arr[one++] = temp;
}
else //查找失敗
{
break;
}
}
for(int i = 0; i<size; i++)
{
printf("%d\n", arr[i]);
}
}