题面
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
示例:
输入:nums = [1,2,3,4]
输出:[1,3,2,4]
注:[3,1,2,4] 也是正确的答案之一。提示:
0 <= nums.length <= 50000 1 <= nums[i] <= 10000
分析
刚开始想到思路1:
从前向后遍历数组,遇到奇数时,什么也不做;遇到偶数时,把该偶数删除,然后把该偶数放到数组后面
但是这种思路会超时
下面分析超时原因:
数组最大长度为50000,思路1绝不仅仅是简单的遍历数组,时间复杂度为O(N),思路1还涉及到数组的插入、删除,删除操作(erase)的复杂度就是O(N),最坏情况下,时间复杂度为O(N2),太大。
接下来想到思路2:
采用双指针,left指向数组首部,right指向数组尾部,left总体趋势向右移动,right总体趋势向左移动
下面分析这种思路不超时的原因:
只遍历数组一遍,时间复杂度为O(N)。
源代码(注释部分即为思路)
class Solution {
public:
vector<int> exchange(vector<int>& nums) {
int len = nums.size();
int left = 0;
int right = len-1;
while(left<right){
//左偶、右奇
if(nums[left]%2==0 && nums[right]%2==1){
//交换数组元素的操作其实很简单,时间复杂度O(1),空间复杂度O(1)
int tmpL = nums[left];
int tmpR = nums[right];
nums[left] = tmpR;
nums[right] = tmpL;
left++;
right--;
}
//左偶、右偶
if(nums[left]%2==0 && nums[right]%2==0){
right--;
}
//左奇、右偶
if(nums[left]%2==1 && nums[right]%2==0){
left++;
right--;
}
//左奇、右奇
if(nums[left]%2==1 && nums[right]%2==1){
left++;
}
}
return nums;
}
};
提交结果:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。