剑指offer--调整数组顺序使奇数位于偶数前面

题目描述

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

class Solution {

public:

void reOrderArray(vector<int> &array) {

if (array.size() == 0)

return;

int length = array.size();

int Find = 0;

int Find2 = 0;

while (Find<length)

{

while (Find<length&&array[Find] % 2 != 0)

{

Find++;//去找偶数

}



Find2 = Find + 1;

while (Find2<length&&array[Find2] % 2 == 0)

{

Find2++;//去找奇数

}

if (Find2 < length)

{

int tmp = array[Find2];

for (int find = Find2 - 1; find >= Find; find--)

{

array[find + 1] = array[find];

}

array[Find++] = tmp;

}

else

{

break;

}

}

}

};

这是经过我很多次修改最终能够通过的代码,这个代码的思想就是我先找到一个偶数,再找到一个奇数,

这里移动的时候一定是先移动找偶数的下标,然后去移动找奇数的下标,找奇数的一定要从找偶数的下标后一个开始,因为找偶数之前的奇数是没有用的,那些是符合题目的。当我们找到第一个偶数和这个偶数后边第一个奇数的时候,我们就需要操作我们的数组,这时候我们应该让9放到2的位置,但是不能是单纯的两个交换数据,因为题目中说了偶数和偶数之间的相对位置是不能变化的,2在4前边那交换完之后2还在4前边,所以我们需要把246这一块数据整体向后移动一个,这就只能借助我们的循环来实现。

if (Find2 < length)

{

int tmp = array[Find2];

for (int find = Find2 - 1; find >= Find; find--)

{

array[find + 1] = array[find];

}

array[Find++] = tmp;

}

我们先把find2的数据记录下来因为,这移动过去会把他原有的数据覆盖掉,然后开始从后往前一个一个移动,等2位置的数据空下来之后把9放进去就可以了,这里的array[Find++] = tmp;是后置++,千万不可写成前置。因为我们是把数据放到tmp之后让Find++的。

  这个程序需要注意的是我们的边界值也就是Find和Find2和我们数组长度length的关系,不能访问越界。while (Find<length&&array[Find] % 2 != 0)还有就是说了很多次的这个&&前后关系,不能颠倒位置,颠倒位置的话如果Find==length这时候,还没进行Find<length判断,就已经访问&array[Find] % 2 != 0位置的数据了。所以如果位置写反很有可能会出现数组越界的情况。

class Solution {

public:

void reOrderArray(vector<int> &array) {

for (int i = 0; i < array.size(); i++)

{

for (int j = array.size() - 1; j>i; j--)

{

if (array[j] % 2 == 1 && array[j - 1] % 2 == 0) //前偶后奇交换

{

swap(array[j], array[j - 1]);

}

}

}

}

};

这是通过冒泡排序的一种思想,遍历每两个位置,如果前边是偶数后边是奇数就进行交换。

还有一种思想就是我们再创建一个新的数组,我们可以先将旧数组中的奇数一个一个拿出来,然后一个一个插入进去,然后再去遍历一边把偶数再按顺序插入到后边,这是一种也有一种是,我们把旧数组中的偶数拿出来,然后把奇数存好,之后再把新数组中的偶数插入到原来旧数组中,两种方式都是可以的。没有什么差别,因为我们这是vector数组实现这些功能就会简单很多。

class Solution{

public:

void reOrderArray(vector<int> &array) {



vector<int> array_temp;

vector<int>::iterator ib1, ie1;

ib1 = array.begin();





for (; ib1 != array.end();){            //遇见偶数,就保存到新数组,同时从原数组中删除

if (*ib1 % 2 == 0) {

array_temp.push_back(*ib1);

ib1 = array.erase(ib1);

}

else{

ib1++;

}



}

vector<int>::iterator ib2, ie2;

ib2 = array_temp.begin();

ie2 = array_temp.end();



for (; ib2 != ie2; ib2++)             //将新数组的数添加到老数组

{

array.push_back(*ib2);

}

}

};

vector<int> array_temp;

vector<int>::iterator ib1, ie1;

ib1 = array.begin();

这里第一句是创建一个vector数组,然后创建两个迭代器,其实说白了就是我们平时创建的int类型的下标,迭代器(Iterator)模式,又叫做游标(Cursor)模式。GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。 从定义可见,迭代器模式是为容器而生。这里就不多说了

 

array_temp.push_back(*ib1);

ib1 = array.erase(ib1);

这里也都是直接调用我们的vector函数,先是把我们ib1指向的元素插入到我们的新数组中,然后把老数组对应的数据删除掉,

for (; ib2 != ie2; ib2++)             //将新数组的数添加到老数组

{

array.push_back(*ib2);

}

然后将我们的新数组中的数据插入到老数组后边。

  对于vector的迭代器我了解的也不是很多,所以就不过多的介绍了如果有想了解的

https://www.cnblogs.com/hdk1993/p/4419779.html 可以去看这个博客。讲的还是比较细的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值