双指针
lo指针指向数组前,hi指针指向数组尾部,lo指针向后移动直至指向的元素为偶数,hi指针向前移动直至指向的元素为奇数,然后交换两个指针所指元数的位置。
class Solution {
public int[] exchange(int[] nums) {
int lo = 0, hi = nums.length - 1;
while(hi > lo){
//向后移动指针lo直到遇到一个偶数
while(lo < hi && (nums[lo] & 0x01) != 0){//与运算判断奇偶速度更快
++lo;
}
//向前移动指针hi直到遇到一个奇数
while(lo < hi && (nums[hi] & 0x01) == 0){
--hi;
}
if(lo < hi){
exch(nums, lo, hi);
}
}
return nums;
}
private void exch(int[] nums, int lo, int hi){
int temp = nums[lo];
nums[lo] = nums[hi];
nums[hi] = temp;
}
}
可扩展解法
与这题类似的问题可能还有:
1、把负数移动到非负数前面
2、把能被3整除的数,移动到不能被3整除的数前面
这一类问题都属于类似问题,只需要改变代码中的判断标准,因此在java中可以使用策略模式来设计一个函数,可以求解一类问题。需要做的只是实现CompareHandler接口,实现其中的handler方法。不同的实现方式对应解决类似的问题。
class Solution {
public int[] exchange(int[] nums) {
return exchange(nums, new IsEven());
}
private int[] exchange(int[] nums, CompareHandler cmpHandler){
int lo = 0, hi = nums.length - 1;
while(lo < hi){
while(lo < hi && !cmpHandler.handler(nums[lo])){
++lo;
}
while(lo < hi && cmpHandler.handler(nums[hi])){
--hi;
}
if(lo < hi){
exch(nums, lo, hi);
}
}
return nums;
}
private void exch(int[] nums, int lo, int hi){
int temp = nums[lo];
nums[lo] = nums[hi];
nums[hi] = temp;
}
interface CompareHandler {
boolean handler(int num);
}
class IsEven implements CompareHandler {
public boolean handler(int num){
if((num & 0x01) == 0)
return true;
return false;
}
}
}