[leetCode]剑指 Offer 21. 调整数组顺序使奇数位于偶数前面

在这里插入图片描述

双指针

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;
        }
    }
}
posted @ 2020-08-17 13:45  消灭猕猴桃  阅读(68)  评论(0编辑  收藏  举报