一、题目描述
描述
输入一个长度为 n 整数数组,数组里面可能含有相同的元素,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前面部分,所有的偶数位于数组的后面部分,对奇数和奇数,偶数和偶数之间的相对位置不做要求,但是时间复杂度和空间复杂度必须如下要求。
数据范围:0 ≤ n ≤50000,数组中每个数的值 0 ≤val ≤10000
要求:时间复杂度 O(n),空间复杂度 O(1)
示例1
输入:[1,2,3,4]
返回值:[1,3,2,4]
说明:[3,1,2,4]或者[3,1,4,2]也是正确答案
示例2
输入:[1,3,5,6,7]
返回值:[1,3,5,7,6]
说明:[3,1,5,7,6]等也是正确答案
示例3
输入:[1,4,4,3]
返回值:[1,3,4,4]
二、解题思路
1. 双指针
- 时间复杂度:O(n),其中n为数组的长度,遍历2次数组
- 空间复杂度:O(1),res数组属于返回函数必要数组,不算额外空间
【C++解法】
class Solution {
public:
vector<int> reOrderArrayTwo(vector<int>& array) {
int len = array.size();
vector<int> res(len);
int odd = 0;
for (int i = 0; i < len; i++) {
if (array[i] % 2 == 1) {
odd++;
}
}
int x = 0;
int y = odd;
for (int i = 0; i < len; i++) {
array[i] % 2 == 1 ? res[x++] = array[i] : res[y++] = array[i];
}
return res;
}
};
【Java解法】
import java.util.*;
public class Solution {
public int[] reOrderArrayTwo (int[] array) {
int len = array.length;
int[] res = new int[len];
int odd = 0;
for (int i = 0; i < len; i++) {
if (array[i] % 2 == 1) {
odd++;
}
}
int x = 0;
int y = odd;
for (int i = 0; i < len; i++) {
if (array[i] % 2 == 1) {
res[x++] = array[i];
} else {
res[y++] = array[i];
}
}
return res;
}
}
2. 双指针交换
这道题不要求相对位置不变,因此我们可以采用位置交换的方法,将奇数全部换到前面。
- 时间复杂度:O(n),其中n为数组的长度,双指针最多只遍历数组一次
- 空间复杂度:O(1),常数级变量,无额外辅助空间
【C++解法】
class Solution {
public:
vector<int> reOrderArrayTwo(vector<int>& array) {
int i = 0;
int j = array.size() - 1;
while (i < j) {
if (array[i] % 2 == 1) {
i++;
if (array[j] % 2 == 0) j--;
} else {
if (array[j] % 2 == 0) j--;
else {
int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
}
}
return array;
}
};
【Java解法】
import java.util.*;
public class Solution {
public int[] reOrderArrayTwo (int[] array) {
int i = 0;
int j = array.length - 1;
while (i < j) {
if (array[i] % 2 == 1 && array[j] % 2 == 1) {
i++;
} else if (array[i] % 2 == 1 && array[j] % 2 == 0) {
i++;
j--;
} else if (array[i] % 2 == 0 && array[j] % 2 == 1) {
int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
} else {
j--;
}
}
return array;
}
}
三、相关题目
《剑指offer》21--调整数组顺序使奇数位于偶数前面[C++][Java]