题目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;
}