面试题14:调整数组顺序使奇数位于偶数前面、链表按奇偶拆分

题目1:输入一个数组,实现一个函数调整该数组中的数字顺序,使得奇数在前,偶数在后。

思路:快速排序的分区思想,设置首尾两指针,找到前半部分的偶数和后半部分的奇数,交换即可。

算法复杂度为O(n)。

代码如下:

void ReorderOddEven(vector<int> &data)
{
	int size = data.size();
	int p = 0, q = size-1;
	while(1)
	{
		while(p<q && (data[p] & 0x1) != 0)
		{
			p++;
		}

		while((data[q] & 0x1) == 0)
		{
			q--;
		}

		if(p<q)
		{
			int tmp = data[p];
			data[p] = data[q];
			data[q] = tmp;
		}
		else
		{
			break;
		}
	}
}

判断奇偶,用&运算来计算,a & 0x1 = 0即是偶数,否则为奇数。

如果要保证原来的相对顺序保持不变呢?即保证奇数和奇数,偶数和偶数之间的相对位置不变。

上面的方法就不能用了,得要用平移数组的方式。
每次遍历到奇数,就将前面所有的偶数都往后平移一位,再把该奇数插入到之前的最后一个奇数后面。
代码如下:

void reOrderArray(vector<int> &array) {
   int size = array.size();
   int last_odd = 0;
   for (int i = 0; i < size; ++i) {
     if (array[i] & 1 == 1) {//如果是奇数
       int tmp = array[i];
       //前面所有的偶数往后平移
       for (int j = i; j > last_odd; --j) {
         array[j] = array[j-1];
       }
       //把该奇数插入到之前的最后一个奇数后面
       array[last_odd++] = tmp;
     }
   }
 }

题目2:把一个单链表按奇偶数拆分

思路:构造头节点

vector<ListNode*> seperate(ListNode* head)
{
	ListNode* h1 = new ListNode(0);
	ListNode* h2 = new ListNode(1);
	ListNode* p = head;
	ListNode* r = h1;
	ListNode* s = h2;

	while(p)
	{
		if(p->val %2 == 0)
		{
			r->next = p;
			r = r->next;
		}
		else
		{
			s->next = p;
			s = s->next;
		}
		p = p->next;
	}

	r->next = NULL;
	s->next = NULL;
	h1 = h1->next;
	h2 = h2->next;
	vector<ListNode*> ret;
	ret.reserve(2);
	ret.push_back(h1);
	ret.push_back(h2);
	return ret;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值