题目:
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
思路
1、相对位置不变
- 可以申请空间
创建双向队列,遍历数组,奇数前插入,偶数后插入。
最后使用assign方法实现不同容器但相容的类型赋值。
- 不可以申请空间
设置两个指针:
**首先,begin从左向右遍历,找到第一个偶数;
然后,from从begin+1开始向后找,直到找到第一个奇数;
接着,将[begin,…,from-1]的元素整体后移一位;
最后将找到的奇数放入begin位置,然后begin++。**
2、相对位置可以改变(快排思想)
如果是强解的话,就可以从头扫描这个数组,每碰到一个偶数时,拿出这个数字,并把位于这个数字后面的所有数字都往前挪动一位,这种解法显然是O(n^2)的,不用想都知道,这不可能通过测试的。
其实,数组类的问题,尤其是这种分为两部分的,我们都可以借鉴快排思想。
**首先,设置前指针指向第一个数,并且只向后移动;
然后,.设置第二个指针指向最后一个数,并且只向前移动;
最后,在两个指针相遇之前,第一个指针总是位于第二个指针的前面。如果第一个指针指向的数字是偶数,并且第二个指针指向的数字是奇数,我们就交换这两个数字。**
/*
@author:axin
2018/07/03
*/
#include <iostream>
#include <vector>
#include <deque>
using namespace std;
class Solution
{
public:
//相对位置不变,可以申请空间
void reOrderArray(vector<int> & array)
{
deque<int> result;
int len = array.size();
if (len == 0)
return;
//一次遍历,从前找偶数,从后找奇数,减少一次遍历
for (int i = 0; i < len; i++)
{
if (array[len - 1 - i] % 2 == 1)
result.push_front(array[len - 1 - i]);
if (array[i] % 2 == 0)
result.push_back(array[i]);
}
//不同容器但相容的类型赋值
array.assign(result.begin(), result.end());
}
};
int main()
{
Solution s;
vector<int> array{1,2,3,4,6,8,10,9,7};
s.reOrderArray(array);
for (auto i : array)
cout << i;
cout << endl;
system("pause");
return 0;
}
class Solution
{
public:
//相对位置不变,不能使用空间
void reOrderArray(vector<int> & array)
{
int len = array.size();
if (len == 0)
return;
int index_even = 0, index_odd; //奇数 偶数
while (index_even < len) //从头开始扫描偶数,直到最后
{
while (index_even < len && (array[index_even] & 0x1) == 1) //是奇数,不是偶数,enen++
++index_even;
index_odd = index_even + 1;
while (index_odd < len && (array[index_odd] & 0x1) == 0)
++index_odd;
if (index_odd < len)
{
int temp = array[index_odd];
for (int i = index_odd; i > index_even; i--)
{
array[i] = array[i - 1];
}
array[index_even] = temp;
}
else break;
}
}
};
//剑指offer书上的,相对位置变化不介意
private static void ReorderArray(int[] arr){
int left = 0;
int right = arr.length-1;
while(left<right){
while(left<right && (arr[left]&1)==1)//使用位运算判断奇偶
left++;//arr[left]为奇数,自增直至为偶数为止
while(left<right && (arr[right]&1)!=1)
right--;//arr[right]为偶数,自减直至为奇数为止
//arr[left]为偶数,arr[right]为奇数,交换
if(left<right){
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
}
}
return语句用来结束循环,或返回一个函数的值。
1、 return, 如果什么都不接的话,其实就是void类型函数的返回,返回后不再执行return后面的语句
如果函数执行成功返回0,不成功返回非0,一般情况下非0值常用-1来表示。
2 、return 0:一般用在主函数结束时,表示程序正常终止,即告诉系统程序正常。
3 、return -1::表示返回一个代数值,一般用在子函数结尾。表示程序异常终止,即告诉系统程序异常
4、 return 1:与return -1相同。