题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
思路1
创建一个原数组的克隆数组,然后一一遍历,判断奇偶性。
空间复杂度O(N),时间复杂度O(N)。
思路1的代码
class Solution {
public:
void reOrderArray(vector<int> &array) {
if (array.empty())
return;
vector<int> help(array);
int oddNum = 0;
for (auto value : array){
if (value & 0x1)
oddNum++;
}
int i = 0, j = oddNum;
for (int k = 0; k < array.size(); k++){
if (help[k] & 0x1)
array[i++] = help[k];
else
array[j++] = help[k];
}
}
};
思路2
类似于插值排序。因为题意要求奇数在左边,偶数在右边。则用一个指针记录奇数区间的右界。
以【1,2,3,4,5,6,7】为例子
(1)初始时,指针为-1,代表下标-1左边都为奇数(包括下标-1)
(2)遍历数组,下标为0时,值为1(奇数),判断指针位置(-1)与当前位置0的关系,距离为1(0-(-1)=1),直接将指针向右移动一位,指向下标0,继续遍历
(3)遍历数组,下标为1时,值为2(偶数),继续遍历
(4)遍历数组,下标为2时,值为3(奇数),判断指针位置(0)与当前位置2的关系,距离为2,则将下标0与下标2之间的数往后移动一位,然后将指针右移一位,将当前位置2的数(移动之前就保存了)放到指针位置上,继续遍历
(5)....以此类推
思路2的代码
class Solution {
public:
void reOrderArray(vector<int> &array) {
int n = array.size();
if (n <= 1) return;
int left = -1;
for (int i = 0; i < n; ++i){
if (array[i] & 0x1){
left++;
if (i - left > 0){
int temp = array[i];
for (int j = i; j > left; --j)
array[j] = array[j-1];
array[left] = temp;
}
}
}
}
};