牛客网刷题之调整数组顺序使奇数位于偶数前面。

我的思路:(很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]);
	}
}

猜你喜欢

转载自blog.csdn.net/USA_AM_1966/article/details/83576790
今日推荐