Day21 2023/01/28
难度:简单
题目
输入一个长度为 n 整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前面部分,所有的偶数位于数组的后面部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
数据范围:0≤n≤5000,数组中每个数的值 0≤val≤10000
要求:时间复杂度,空间复杂度
进阶:时间复杂度 ,空间复杂度
示例
输入:[1,2,3,4]
输出:[1,3,2,4]
思路一
创建两个额外的数组,遍历原数组分别存储数组中的奇数元素和偶数元素,然后按照题目要求合并即可(奇数元素在偶数元素前面)。
具体做法:
- 遍历原数组,判断元素如果为奇数加入奇数数组,如果为偶数加入偶数数组。
- 将偶数数组合并到奇数数组的末尾,并返回。
思路二
采用双指针法,仅在原数组上修改,一个指针用来表示下一个待插入的奇数元素的下标(初始为0),一个指针用来遍历寻找奇数元素(初始为0)。
具体做法:
- 遍历原数组,如果元素为偶数就跳过,如果元素为奇数,则将该元素前(不包括自己)的所有元素整体后移一位,再将该元素赋值到表示下一个待插入的奇数元素的下标的指针上,然后该指针加1。
说明
odd.insert(position, first, last );其中 position 表示数组中插入第一个元素的位置; first 表示要赋值范围元素中的第一个元素的位置; last 表示要赋值的元素范围以外的第一个元素的位置。
算法实现
c++代码实现1-辅助数组
class Solution {
public:
vector<int> reOrderArray(vector<int>& array) {
vector<int> odd; //存储奇数元素
vector<int> even; //存储偶数元素
for (int val : array) { //遍历将元素加入数组
if (val % 2 == 0) even.push_back(val);
else odd.push_back(val);
}
odd.insert(odd.end(), even.begin(), even.end()); //将偶数数组合并到奇数数组的末尾。
return odd;
}
};
- 时间复杂度 --- 遍历原数组,n为数组长度
- 空间复杂度 --- m为辅助数组的长度
c++代码实现2-双指针
class Solution {
public:
vector<int> reOrderArray(vector<int>& array) {
int i = 0; //表待插入奇数元素的下标
for (int j = 0; j < array.size(); j++) {
if (array[j] % 2 == 1) {
int tmp = array[j]; //中间变量
for (int k = j - 1; k >= i; k--) array[k + 1] = array[k]; //将[i]~[j-1]的元素整体向后移动一位
array[i++] = tmp;
}
}
return array;
}
};
- 时间复杂度 --- 最差的情况原数组一半偶数在前,一半奇数在后,每次都要移动n/2个元素,一共移动
- 空间复杂度 --- 无额外辅助空间
总结
- 方法一为空间换时间,方法二为时间换空间。