调整数组顺序使奇数位于偶数前面

<span style="font-family: arial, STHeiti, 'Microsoft YaHei', 宋体; background-color: rgb(255, 255, 255);">题目描述</span>

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。

注意:本题需要保持奇数与奇数之间,偶数和偶数之间的相对位置不改变,所以就不能使用快排的partition,因为快排是不稳定的,这里提供几种方法。

法1:类似于冒泡排序,如果前面是偶数,后面是奇数,则交换两者的位置。

代码如下:

class Solution {
public:
	void reOrderArray(vector<int> &array) 
	{
		for (int P = array.size() - 1; P > 0; --P)
		{
			bool flag = false; //默认无交换
			for (int i = 0; i < P; ++i)
			{
				if (((array[i] & 1) == 0) && ((array[i + 1] & 1) != 0))
				{
					swap(array[i], array[i + 1]);
					flag = true;
				}
			}
			if (flag == false)
				break;
		}		
	}
};

法2: 类似于插入排序,如果当前的数字是奇数,则将其前面的数字全部往后挪一个空位出来,将该数字插入。

代码如下:

class Solution {
public:
	void reOrderArray(vector<int> &array) 
	{
		for (int P = 1; P < array.size(); ++P)
		{
			int Tmp = array[P];
			if ((array[P] & 1) == 0) //如果是偶数,继续下一个数字
				continue;
			else
			{
				int i;
				for (i = P; i > 0 && (array[i - 1] & 1) == 0; --i)
				{
					array[i] = array[i - 1];
				}
				array[i] = Tmp;
			}
		}
	}
};

上述两种方法的时间复杂度都是O(n^2);

法3:类似于归并排序,时间复杂度可降低到O(nlogn)

代码如下:

class Solution {
public:
	void reOrderArray(vector<int> &array) 
	{
		vector<int> temp(array.size());
		helpReorder(array, temp, 0, array.size() - 1);
	}

public:
	void helpReorder(vector<int> &array, vector<int> &TmpArr, int L, int RightEnd)
	{
		if (L < RightEnd)
		{
			int center = (L + RightEnd) / 2;
			helpReorder(array, TmpArr, L, center);
			helpReorder(array, TmpArr, center+1, RightEnd);
			Merge(array, TmpArr, L, center + 1, RightEnd);
		}
	}
		
	void Merge(vector<int> &array, vector<int> &TmpArr, int L, int R, int RightEnd)
	{
		int leftEnd = R - 1;
		int Tmp = L;
		int NumberofElem = RightEnd - L + 1;

		while (L <= leftEnd && (array[L] & 1) != 0)
		{
			TmpArr[Tmp++] = array[L++];
		}
		while (R <= RightEnd && (array[R] & 1) != 0)
		{
			TmpArr[Tmp++] = array[R++];
		}
		while (L <= leftEnd && (array[L] & 1) == 0)
		{
			TmpArr[Tmp++] = array[L++];
		}
		while (R <= RightEnd && (array[R] & 1) == 0)
		{
			TmpArr[Tmp++] = array[R++];
		}

		for (int i = 0; i < NumberofElem; ++i,RightEnd--)
		{
			array[RightEnd] = TmpArr[RightEnd];
		}
	}
};





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值