题目: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
最直接的想法是:从头到尾扫描这个数组,如果遇到偶数时,将这个偶数取出,将后面的每个数字往前挪一位,最后将取出的偶数放置在最后的位置上。每次取出一个偶数,后面的数都需要移动,所以时间复杂度 O(n2)
考虑双指针解法: 一个指向数组的首部(st),另一个指向数组的尾部(etd),分为如下4种情况,
- st指向的数字为奇数,etd指向的数字为奇数,则st指针向后移动
- st指向的数字为奇数,etd指向的数字为偶数,则st指针向后移动,etd向前移动
- st指向的数字为偶数,etd指向的数字为偶数,则etd向前移动
前面偶数,后面奇数 交换位置,并且 st向后移动,etd向前移动
代码如下:
public class OddBeforeEven14 {
public int[] trans(int[] nums){
//数组为空或者长度小于等于0 返回null
if(nums.length<=0 || nums==null)
return null;
int st =0;
int etd = nums.length-1;
while(st<etd){
//如果前部指针指向偶数,而后面的指针指向奇数,则交换位置 前面的指针向后移一位 后面的指针向前移一位
//前面奇数,后面奇数 前面的指针向后移动
//前面奇数,后面偶数 前面的指针向后移动,后面的指针向前移动
//前面偶数,后面偶数 后面的指针向前移动
//前面偶数,后面奇数 交换位置,并且 前面的指针向后移动,后面的指针向前移动
if(nums[st]%2!=0 && nums[etd]%2!=0){
st++;
}else if(nums[st]%2!=0 && nums[etd]%2==0){
st++;
etd--;
}else if(nums[st]%2==0 && nums[etd]%2==0){
etd--;
}else {
int temp = nums[st];
nums[st]=nums[etd];
nums[etd]=temp;
st++;
etd--;
//System.out.println("...swap");
}
}
return nums;
}
public static void main(String[] args) {
OddBeforeEven14 odd =new OddBeforeEven14();
//exm1
int [] nums = new int[]{1,2,3,4,5,6,7}; // 1,7,3,5,4,6,2
//exm2
int [] nums2 = new int[]{};
nums = odd.trans(nums);
for(int i=0;i<nums.length;i++){
System.out.println(nums[i]+",");
}
nums2 = odd.trans(nums2);
System.out.println(nums2);
}
}