问题1
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
示例:
输入:nums = [1,2,3,4]
输出:[1,3,2,4]
注:[3,1,2,4] 也是正确的答案之一。
题目分析
第一种方法:双指针,一个指针从前往后找偶数,另一个指针从后往前找奇数,然后交换数组顺序,类似快速排序。
class Solution {
public int[] exchange(int[] nums) {
int left = 0;
int right = nums.length-1;
while(left<right) {
//从前往后找偶数
while(left<right) {
if(nums[left] % 2 == 0) {
break;
} else {
left++;
}
}
while(left<right) {
if(nums[right] % 2 == 1) {
break;
} else {
right--;
}
}
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
}
return nums;
}
}
上面的代码虽然能够实现,但是不够简洁,看下面的代码
class Solution {
public int[] exchange(int[] nums) {
int left = 0;
int right = nums.length-1;
while(left<right) {
//找偶数, continue的作用就是不断循坏知道找到一个偶数为止
if(nums[left] % 2 == 1) {
left++;
continue;
}
//找奇数,continue的作用就是不断循坏知道找到一个奇数为止
if(nums[right] % 2 == 0) {
right--;
continue;
}
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
}
return nums;
}
}
第二种方法即是使用快慢指针,慢指针指向奇数下一个存放得位置,快指针寻找奇数,然后不断交换。
class Solution {
public int[] exchange(int[] nums) {
int low = 0;
int fast = 0;
while(fast<nums.length) {
if(nums[fast] % 2 == 1) {
int temp = nums[low];
nums[low] = nums[fast];
nums[fast] = temp;
low++;
}
fast++;
}
return nums;
}
}
题目2
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
示例1
输入
[1,2,3,4]
返回值
[1,3,2,4]
题目分析
相比较上一题,题目加入了限制条件,就是奇数和偶数的相对顺序不能够改变。
如果在不需要额外的空间的情况下可以借鉴冒泡排序的方式,如果有偶数奇数相邻,就交换他们的位置,代码如下:
public int[] reOrderArray (int[] array) {
for(int j = 0;j<array.length;j++) {
for(int i = 0;i<array.length-1;i++) {
//如果偶数和奇数相邻,交换他们的位置
if((array[i] & 1) == 0 && (array[i+1] & 1) == 1) {
int temp = array[i];
array[i] = array[i+1];
array[i+1] = temp;
}
}
}
return array;
}
时间复杂度为o(n^2),至于最外层的遍历次数,最极端的情况就是只有一个奇数在数组的最后一位,需要交换n-1次。